在ManyRelatedManager对象中排序

时间:2009-09-20 20:05:05

标签: django django-models

关于订购,我有一个普遍的问题 ManyRelatedManager对象。例如, 我的模型中有两个类:一个是 名为Book for books,另一本是作者作者。

课堂书中定义了多对多字段     authors = models.ManyToManyField(作者)

在数据库中,多对多关系 在另一个表book_author中描述 有三列:(id,book_id,author_id)

现在对于Book对象b,b.authors.all()和b.authors.iterator() 按book_author.author_id的顺序排序。 但我想要的是检索b的作者 按照book_author.id的顺序,因为这是 作者的正确顺序。

任何解决方案?提前谢谢了!

2 个答案:

答案 0 :(得分:1)

如果您想根据图书订购不同的作者,我建议您使用ManyToMany字段并指定through属性,如下所述: http://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships

如果您的through模型定义了排序列,则可以直接查询through模型,例如

class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField('Author', through='BookAuthor')

class Author(models.Model):
    name = models.CharField(max_length=100)

class BookAuthor(models.Model):
    book = models.ForeignKey(Book)
    author = models.ForeignKey(Author)
    ordering = models.IntegerField()

如果您愿意,现在可以直接查询through模型:

b = Book.objects.get(pk=1)
BookAuthor.objects.filter(book=b).order_by('ordering')

您还可以添加Meta ordering,以便在查询此模型时添加order_by ...

class BookAuthor(models.Model):
    # ...
    ordering = models.IntegerField()

    class Meta:
        ordering = ('ordering',)

现在你可以删除额外的.order_by子句,因为Django会自己添加它。

b = Book.objects.get(pk=1)
BookAuthor.objects.filter(book=b)

注意:即使使用through模型和Meta ordering,Django也不会在查询一方或另一方时添加.order_by,例如以下内容不会添加ORDER BY SQL:

b = Book.objects.get(pk=1)
b.authors.all() # Not ordered

答案 1 :(得分:0)

Book实例的“authors”属性是一个管理器,因此管理器方法order_by()将对其起作用:

book = Book.objects.get(id=1)
authors = book.authors.order_by('-last_name')

(假设作者有“last_name”字段)