【问题标题】:Django Admin: How to sort by data from another model?Django Admin:如何按来自另一个模型的数据排序?
【发布时间】:2014-09-19 16:11:45
【问题描述】:

我在 Django 应用程序中有以下两个模型:EventEventDate。我喜欢在 Event 的管理列表视图中显示一些来自 EventDate 的计算数据并且我希望能够按它排序。

我根据 EventDate 中的数据计算每个 Event下一个即将到来的日期。现在我不仅希望它显示在 EventDjango Admin 列表视图中,而且我还希望按它排序的事件。

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

它在调试 shell 中工作,但我无法让它在管理员中工作。我不知道如何将其包含在 list_display 或其他什么操作中。

【问题讨论】:

  • 为什么不把外键放在Event模型里?这是一个周到的设计,还是您必须在 EventDate 和 Event 之间随机选择?如果我最后一个问题的第二个选项是真的,你可以考虑把外键放在 Event 中,这会让一切变得更容易
  • 另外,请参阅可能有用的答案链接:stackoverflow.com/a/16073402/3768672。以及文档的这一部分:docs.djangoproject.com/en/dev/ref/contrib/admin/…
  • @RaphaelLaurent:一个Event 可以有多个EventDate(这就是我将数据分成两个模型的原因)。如果我正确理解了 Django ORM,那么这就是定义一对多关系的方法。将 FK 放在 Event 上是行不通的。
  • 确实在这种情况下,同意你的模型是有效的
  • @RaphaelLaurent:感谢您提供的链接。但我尝试在 Event 的列表视图中显示附加信息。使用 EventDate 内联效果很好。我尝试在问题中添加更多信息。

标签: python django orm django-admin


【解决方案1】:

似乎我找到了一种方法来使用额外调用中的数据...

我向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 Questions 的答案。如果对我有帮助,我会报告。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-03
    • 2018-08-28
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多