Django 字段选项之 related_name 和 related_query_name

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

Guess you like

Origin blog.csdn.net/qq_39253370/article/details/119984347