我有以下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')
...会将没有作者的出版物聚集在一起,并且根据编辑对该组进行排序,这不是我想要的。实际上,它应该使用任何作者或编辑可用于出版物并按此排序。
这种排序必须在数据库级别进行,结果集可能很大。
答案 0 :(得分: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))
答案 1 :(得分:0)
我可以把它扔出去吗?
您可能希望Authors
和Editors
继承Contributors
。因为这两个模型都有诸如姓名,地址等的东西。
答案 2 :(得分: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的一个实现作为聚合。例如,