Django Admin:如何按另一个模型的数据排序?

0 投票
1 回答
670 浏览
提问于 2025-04-18 15:02

我在一个Django应用里有两个模型:EventEventDate。我想在Event的管理列表中显示一些从EventDate计算出来的数据,并且希望能够根据这些数据进行排序。

我从EventDate的数据中计算出每个Event下一个即将到来的日期。现在我希望这个日期不仅能在EventDjango管理界面中显示,还希望能根据这个日期进行排序。

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的问题的答案。如果它出问题了,我会再报告的。

撰写回答