假设我有以下模型:
class Author(Model):
name = CharField()
class Publication(Model):
name = CharField()
authors = ManyToManyField(Author)
class Meta:
abstract = True
class Book(Publication):
pass
class Article(Publication):
pass
class Journal(Publication):
pass
如何更改代码,以便可以将through
表添加到authors
?如果我写authors = ManyToManyField(Author, through='Relationship')
,它将不起作用。
答案 0 :(得分:-1)
值得庆幸的是,Django无需任何编码即可处理中间表。您甚至可以使用M2M关系管理器上的.through
访问它们,例如one_publication.authors.through
。
如果您要自己管理贯通表,只需指定它即可。因为您要添加的字段不仅仅是两个相关实体的外键。是这样吗?
如果是,则必须创建一个Relationship
模型(考虑提供一个更有用的名称),其中包含指向Publication
和Author
的外键。
更新:如果要向多对多关系中的对象列表添加默认顺序,则中间模型确实是实现此目的的一种方法:
class Relationship(models.Model):
author = models.ForeignKey(Author)
publication = models.ForeignKey(Publication)
# Any further fields that you need
class Meta:
ordering = ['author__last_name', 'author__first_name']
但是,您可以在查询m2m关系时轻松地对其进行排序,而无需任何中间模型或通过管理器:
book = Book.objects.first()
for author in book.authors.order_by('last_name', 'first_name'):
# Will print in alphabetical order
print(f'Author: {author.first_name} {author.last_name}')
一个警告是,如果使用预取,则需要在Prefetch对象中指定顺序,以避免执行两次查询,首先是不带顺序的预取,而不是带顺序的访问。
# 2 queries plus one for every book
books = Book.objects.prefetch_related('authors')
for book in books:
for author in book.authors.order_by('last_name', 'first_name'):
print(f'Author: {author.first_name} {author.last_name}')
# 2 queries regardless of number of books
books = Book.objects.prefetch_related(Prefetch('authors',
queryset=Author.objects.order_by('last_name', 'first_name')))
for book in books:
for author in book.authors.all():
print(f'Author: {author.first_name} {author.last_name}')