from django.db import models
# Create your models here.
class Author(models.Model):
name = models.CharField(verbose_name='姓名', max_length=50)
age = models.IntegerField(verbose_name='年龄')
class Book(models.Model):
name = models.CharField(verbose_name='书名', max_length=100)
author = models.ForeignKey(Author, verbose_name='作者')
执行语句:
>>> Author.objects.filter(book__name='learn java')
[<Author: jim>]
>>> author = Author.objects.get(pk=1)
>>> author.book_set.all()
[<Book: learn java>, <Book: learn python>]
假如把类 Book 改成这样:
class Book(models.Model):
name = models.CharField(verbose_name='书名', max_length=100)
author = models.ForeignKey(Author, verbose_name='作者', related_name='bs', related_query_name='b')
那么上面查询代码就应该写成这样:
>>> Author.objects.filter(b__name='learn java')
[<Author: jim>]
>>> author = Author.objects.get(pk=1)
>>> author.bs.all()
[<Book: learn java>, <Book: learn python>]
如果 book 表里有两个字段都外键关联 author 表,这时 related_name 就非常有用了。
以上可能大家看得懂,但是不知道为什么这样去做,或者适用场景是什么样的,这里就解释一下:
related_name: related_name将是相关对象的属性,它允许您“向后”到带有外键的模型。例如,如果ModelA有这样的字段:
author = models.ForeignKey(Author, verbose_name=‘作者’,related_name=‘bs’),这将使您能够通过 bs 访问与您的 Author 实例相关的实例bs_instance.model_as.all(), 但是需要注意一点的是这一般是用复数表示外键, 因为外键是一对多的关系, 该方式其实是声明外键字段的模型, 如果没有声明则是表明加下划线_set, 如:author_set。
related_query_name: related_query_name用于 Django 查询集。它允许您过滤外键相关字段的反向关系。如:有一个字段 author = models.ForeignKey(Author, verbose_name=‘作者’, related_name=‘bs’, related_query_name=‘b’) 将使您能够b在查询集中用作查找参数,例如:Author.objects.filter(b__name=‘whatever’)。它将使用单数形式 related_query_name。
官网说到:没有必要同时指定(或其中之一)related_name和related_query_name, Django 有合理的默认值。
参考文献
官网:https://docs.djangoproject.com/en/dev/topics/db/queries/#backwards-related-objects
stackoverflow: https://stackoverflow.com/questions/43132872/difference-between-related-name-and-related-query-name-attributes-in-django/43133136