Django Admin:如何按另一个模型的数据排序?
我在一个Django应用里有两个模型:Event
和EventDate
。我想在Event的管理列表中显示一些从EventDate计算出来的数据,并且希望能够根据这些数据进行排序。
我从EventDate的数据中计算出每个Event的下一个即将到来的日期。现在我希望这个日期不仅能在Event
的Django管理界面中显示,还希望能根据这个日期进行排序。
Django模型大致长这样:
class EventDate(models.Model):
date = models.DateField(db_index=True)
start = models.TimeField(blank=True, null=True)
end = models.TimeField(blank=True, null=True)
event = models.ForeignKey('Event')
class Event(TimeStampedModel):
title = models.CharField(max_length=200)
text = models.TextField()
published = models.BooleanField(default=False, db_index=True)
我到目前为止尝试过的
首先,我给我的Event模型添加了一个属性,这个属性返回下一个日期,这样做有点效果:我可以在list_display
中显示下一个日期,甚至可以用prefetch_related
来优化。但问题是,我无法在列表中根据这个字段进行排序 :(
接下来,我尝试用extra
来扩展模型,以绕过这个限制……虽然这样做不太优雅,但我想出了这个办法:
class EventAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super(EventAdmin, self).get_queryset(request)
qs.extra(
select={
'n2': """SELECT MIN(events_eventdate.date) FROM events_eventdate
WHERE events_event.id == events_eventdate.event_id AND
events_eventdate.date >= '{}'
""".format(now().date().isoformat())
}
)
return qs
这个方法在调试环境中可以工作,但我不知道怎么在管理界面中使用它,也不知道该如何将其包含在list_display
中,或者还需要做些什么。
1 个回答
0
看起来我找到了一种方法,可以使用额外调用的数据...
我在 EventAdmin
中添加了一个方法,并把 admin_order_field
设置为由额外调用生成的字段:
class EventAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super(EventAdmin, self).get_queryset(request)
qs = qs.prefetch_related('eventdate_set')
qs = qs.extra(
select={
'next_date': """SELECT MIN(events_eventdate.date)
FROM events_eventdate
WHERE events_event.id == events_eventdate.event_id AND
events_eventdate.date >= '{}'
""".format(now().date().isoformat())
}
)
return qs
def next_date(self, obj):
try:
return obj.next_date
except IndexError:
return 'abgelaufen'
next_date.short_description = 'Nächster Termin'
next_date.admin_order_field = 'next_date'
我不确定这样做是否干净或者合理……不过它似乎能正常工作,我就这样做了,因为在这里很难找到关于Django的问题的答案。如果它出问题了,我会再报告的。