先看个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()访问
来源:https://www.cnblogs.com/zengchunyun/p/5560930.html