• Django 中related_name,"%(app_label)s_%(class)s_related"


    先看个model

     1 from django.db import models
     2 
     3 # Create your models here.
     4 
     5 
     6 class Parent(models.Model):
     7     name = models.CharField(max_length=64, verbose_name=u'姓名')
     8     id_num = models.BigIntegerField(verbose_name=u'身份证号', unique=True)
     9 
    10     def __str__(self):
    11         return self.name
    12 
    13     class Meta:
    14         verbose_name = u'父亲'
    15         verbose_name_plural = u'父亲'
    16 
    17 
    18 class Mother(models.Model):
    19     name = models.CharField(max_length=64, verbose_name=u'姓名')
    20     id_num = models.BigIntegerField(verbose_name=u'身份证号', unique=True)
    21 
    22     def __str__(self):
    23         return self.name
    24 
    25     class Meta:
    26         verbose_name = u'母亲'
    27         verbose_name_plural = u'母亲'
    28 
    29 
    30 class Brothers(models.Model):
    31     name = models.ManyToManyField('Child', verbose_name=u'我的兄弟')
    32 
    33     class Meta:
    34         verbose_name = u'兄弟'
    35         verbose_name_plural = u'兄弟'
    36 
    37 
    38 class Child(models.Model):
    39     name = models.CharField(verbose_name=u'我的姓名', max_length=60)
    40     my_parent = models.ForeignKey('Parent', verbose_name=u'我的父亲')
    41     my_mother = models.ForeignKey('Mother', verbose_name=u'我的母亲', related_name="%(app_label)s_%(class)s_related")
    42     my_big_brother = models.ForeignKey('self', related_name="%(app_label)s_%(class)s_related_little_brother", blank=True, null=True, verbose_name=u'我大哥')
    43 
    44     def __str__(self):
    45         return "%s" % self.name
    46 
    47     class Meta:
    48         verbose_name = u'儿子'
    49         verbose_name_plural = u'儿子'
    50         unique_together = ('name', 'my_parent', 'my_mother')

    通过这个model,我们提前插入了些数据,下面是关于这个model 查找方法

     1 from django.shortcuts import render,HttpResponse
     2 from family import models
     3 
     4 # Create your views here.
     5 
     6 
     7 def index(request):
     8     all_child= models.Child.objects.all()
     9     print(all_child)  # 所有孩子
    10     little = models.Child.objects.filter(name='小耀耀')
    11     print(little)  # 找到小耀耀这个孩子
    12     print(little[0].my_mother)  # 他妈妈
    13     print(little[0].my_parent)  # 他爸爸
    14     print(little[0].my_big_brother)  # 他大哥
    15     print(little[0].family_child_related_little_brother.select_related())  # 他的兄弟
    16     all_mother = models.Mother.objects.all()
    17     all_father = models.Parent.objects.all()
    18     print(all_mother, all_father)
    19     print(all_mother.get(name='李冰冰'))  # 找到李冰冰
    20     libingbing = all_mother.get(name='李冰冰')
    21     print(libingbing.family_child_related.select_related())  # 李冰冰所有的儿子
    22     print(all_father.get(name='刘子凡'))  # 找到刘子凡
    23     liuzifan = all_father.get(name='刘子凡')
    24     print(liuzifan.child_set.select_related())  # 找到刘子凡的所有儿子
    all_brothers = models.Brothers.objects.all()
    print(all_brothers[0]) # 取第一个兄弟成员
    print(all_brothers[0].name.select_related())

    25 return HttpResponse(all_child)

    下面是显示结果

     1 [<Child: 小毛>, <Child: 小花>, <Child: 小黑>, <Child: 小耀耀>, <Child: 小耀耀他弟>, <Child: 小子凡>, <Child: 小子凡他弟>, <Child: 小小子凡>]
     2 [<Child: 小耀耀>]
     3 范冰冰
     4 刘耀
     5 小毛
     6 [<Child: 小耀耀他弟>]
     7 [<Mother: 宋慧乔>, <Mother: 范冰冰>, <Mother: 李冰冰>] [<Parent: 曾春云>, <Parent: 刘子凡>, <Parent: 刘耀>]
     8 李冰冰
     9 [<Child: 小花>, <Child: 小黑>, <Child: 小子凡>, <Child: 小子凡他弟>, <Child: 小小子凡>]
    10 刘子凡
    11 [<Child: 小毛>, <Child: 小黑>, <Child: 小子凡>, <Child: 小子凡他弟>, <Child: 小小子凡>]

    对于foreignkey字段,

      如果要查询my_parent或my_mother,可以直接通过child对象.my_mother形式找到母亲是谁,可是我们如何通过母亲或父亲找到自己的儿子是谁呢?

      ,这个分两种情况,一种是,如果我们对儿子设置了related_name时,需要以related_name去获取, 默认情况在没有设置related_name时,一般都是以model_name+'_set'字符串形式拼接

      访问他的孩子

      related_name优先覆盖默认的model_name+'_set'这种访问方式

    通常反向查找不是直接上面这样就能获取到数据的,还需要结合select_related()方法,才能获取到数据

    对于many_to_many

      以brother表为例,该name是多对多字段,要访问brother每个对象的兄弟,分两种情况

        brother表字段name,没有设置related_name,那么怎么通过child查找兄弟呢?可以通过child.brother_set访问,注意,该child是child  queryset对象,不是modelname,即,child. +  brother表的model name+‘_set’拼接的结果访问little就相当于这里的child

    1 little = models.Child.objects.filter(name='小耀耀')
    1     all_brothers = models.Brothers.objects.all()
    2     print(all_brothers[0])  # 取第一个兄弟成员
    3     print(all_brothers[0].name.select_related())
    4     print(little[0].brothers_set.select_related())  # 如果Brother表没有设置related_name,则只能这种方式访问
    5     print(little[0].my_brother.select_related())  # 如果设置related_name则以related_name访问

        与foreign key一样,光这样还是不能获取到值,需要结合select_related()方法

        如果name字段设置了related_name属性,即上面的model改成下面这样,注意,修改model需要同步下数据

    1 class Brothers(models.Model):
    2     name = models.ManyToManyField('Child', verbose_name=u'我的兄弟', related_name='my_brother')

        数据同步完,可以按照下面这种方式访问child的兄弟

        即child.my_brother.select_related()访问

        

      

      

  • 相关阅读:
    原来这样就可以开发出一个百万量级的Android相机
    微信读书这样排版,看过的人都很难忘!
    AI小白快上车!这是发往高薪职位的车!
    短视频APP是如何开启你的美好生活的?
    自从我这样撸代码以后,公司网页的浏览量提高了107%!
    如果想成为一名顶尖的前端,这份书单你一定要收藏!
    老板今天问我为什么公司的数据库这么烂,我是这样回答的......
    MapReduce Notes
    HDFS Architecture Notes
    BloomFilter
  • 原文地址:https://www.cnblogs.com/zengchunyun/p/5560930.html
Copyright © 2020-2023  润新知