反向查询

relationships “backward”

  如果模型I有一个ForeignKey,那么该ForeignKey 所指的模型II实例可以通过一个管理器返回前面有ForeignKey的模型I的所有实例。默认情况下,这个管理器的名字为foo_set,其中foo 是源模型的小写名称。管理器返回的查询集可以用上一节提到的方式进行过滤和操作。

例如:

>>> t = Teacher.objects.get(id=1)
>>> t.student_set.all() # Returns all Entry objects related to Blog.

# t.student_set is a Manager that returns QuerySets.
>>> t.student_set.filter(name__contains='vincen')
>>>  t.student_set.count()

 

你可以在Foreignkey 定义时设置related_name参数来覆盖foo_set 的名称。例如,如果Student模型改成 teacher = ForeignKey(Teacher, related_name='students'),那么上面的示例代码应该改成这样:

>>> t = Teacher.objects.get(id=1)
>>> t.students.all() # Returns all Entry objects related to Blog.

# t.student_set is a Manager that returns QuerySets.
>>> t.students.filter(name__contains='vincen')
>>>  t.students.count()

 

ForeignKey 和 ManyToManyFied 都可以指定 related_name.

一个数据表同时两次外键引用另一个表,出现重名问题:

 

class Apple( models.Model):
    origin_level = models.ForeignKey(AppleLevel)
    new_level = models.ForeignKey(AppleLevel)

 

出现如下问题:

 

monitor.apple: Accessor for field ‘origin_level’ clashes with related field ‘AppleLevel.apple_set’. Add a related_name argument to the definition for ‘origin_level’. 
monitor.apple: Accessor for field ‘new_level’ clashes with related field ‘AppleLevel.apple_set’. Add a related_name argument to the definition for ‘new_level’.

原因:

一个数据表同时两次外键引用另一个表,出现重名问题。

解决办法:

使用related_name属性定义名称(related_name是关联对象反向引用描述符)。 
具体修改代码如下:

class Apple( models.Model):
    origin_level = models.ForeignKey(AppleLevel, related_name='orgin_level_appleset')
    new_level = models.ForeignKey(AppleLevel, related_name='new_level_appleset')

related_name使用之后,有什么用处呢? 
用处就是: 
通过AppleLevel可以得到引用自身的Apple对象。

例如, 
通过origin_level引用AppleLevel 中id为12的Apple的所有对象

AppleLevel.object.get(id=12).origin_level_appleset.objects.all()

 


 

posted @ 2017-05-26 11:07  Vincen_shen  阅读(205)  评论(0)    收藏  举报