【问题标题】:Ordering in the ManyRelatedManager object在 ManyRelatedManager 对象中排序
【发布时间】:2010-11-29 22:16:51
【问题描述】:

我有一个关于订购的一般性问题 ManyRelatedManager 对象。例如, 我的模型中有两个类:一个是 称为 Book for books,另一个是 Author for authors。

在类 Book 中定义了一个多对多字段 作者 = 模型.ManyToManyField(作者)

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

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

有什么解决办法吗?提前谢谢了!

【问题讨论】:

    标签: django django-models


    【解决方案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
    

    【讨论】:

    • 最后一点值得重申:我认为添加一个实现排序的through 模型将允许我的all() 调用神奇地开始自己排序。唉,很多代码需要修改。
    【解决方案2】:

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

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

    (假设您在作者上有一个“姓氏”字段)

    【讨论】:

    • 我相信您还可以在 Authors 上定义默认排序,当您通过管理器查询 Authors 时应该会生效。见docs.djangoproject.com/en/dev/ref/models/options/#ordering
    • 请注意,我想要的排序不取决于作者的属性。实际上对于相同的作者列表,他们可能有不同的顺序,具体取决于书是什么。假设作者 A 和作者 B 合着了两本书。在一本书中,A 是第一本书,而在另一本书中,B 是第一作者。那么我想要的是第一本书的作者顺序是A和B,而第二本书的作者顺序是B和A。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    相关资源
    最近更新 更多