0

我有以下 Django 模型(这里非常简化):

class Author:
    name = models.TextField()

class Editor:
    name = model.TextField()

class Publication:
    authors = models.ManyToManyField(Author)
    editors = models.ManyToManyField(Editor)

出版物可以有作者编辑,但不能同时有两者我想按作者和编辑的统一排序,按字母顺序排列的出版物列表。换句话说,我想按一个虚拟字段排序,我们称之为creators作者和编辑的串联。

查询:

Publication.objects.all().order_by('authors__name', 'editors__name')

...将没有作者的出版物聚集在一起,并在该组中根据编辑进行排序,这不是我想要的。实际上,它应该使用任何可用于出版物的作者或编辑,并按此排序。

这种排序必须发生在数据库级别,结果集可能很大。

4

3 回答 3

0

一种方法是创建一个名为的方法creators

class Publication:
    authors = models.ManyToManyField(Author)
    editors = models.ManyToManyField(Editor)

    def creators(self):
        return self.authors + self.creators

但缺点是不能在数据库级别执行排序,而是在 Python 级别:

sorted(Publication.objects.all(), key=lambda k: " ".join(p.name for p in k))
于 2014-01-21T14:23:38.137 回答
0

我可以把这个扔出去吗?

您可能想要AuthorsEditors继承自Contributors. 因为这两个模型都会有名字和姓氏、地址等内容。

于 2014-01-21T14:44:03.953 回答
0

要按定义了值的任何字段进行排序,您需要在 QuerySet 可以访问的地方创建一个组合字段,无论是在模型级别,使用自定义聚合,还是使用额外的子句。

如果您不需要完全与数据库无关,那么额外的可能是最容易实现的:

qs = Publication.objects.extra({
   select={'contributor': "COALESCE(author.name,editor.name)"}
})
qs.extra(order_by = ['contributor'])

https://docs.djangoproject.com/en/1.6/ref/models/querysets/#django.db.models.query.QuerySet.extra

如果您确实需要独立于数据库,则应该考虑使用 concat 的一种实现作为聚合。例如,

http://harkablog.com/inside-the-django-orm-aggregates.html

于 2014-01-21T15:01:32.453 回答