首页 文章

在ManyRelatedManager对象中排序

提问于
浏览
0

我有一个关于ManyRelatedManager对象中的排序的一般问题 . 例如,我的模型中有两个类:一个叫做Book for books,另一个是作者作者 .

课程中定义了多对多字段Book authors = models.ManyToManyField(Author)

在数据库中,多对多关系在附加表book_author中描述,其中包含三列:(id,book_id,author_id)

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

有解决方案?提前谢谢了!

2 回答

  • 0

    如果您想根据书籍订购不同的作者,我建议使用 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

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

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

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

相关问题