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

瘦欲@ 提交于 2019-12-29 17:19:09

先看个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()访问

    

  

  

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!