【问题标题】:Sorting for custom fields in models in django admin在 django admin 中对模型中的自定义字段进行排序
【发布时间】:2014-06-10 12:49:21
【问题描述】:

我想在 django admin 中为自定义模型字段提供排序功能。

代码类似

class MyModel(models.Model):

    first_name = models.CharField()
    last_name = models.CharField()

    def most_recent_mailing_date(self):
        """ Return the most recent mailing date """
        mailingHistories = self.mailinghistory_set.all()

        if len(mailingHistories) != 0:
            today = datetime.date.today()
            mostRecentHistory = None
            diff = -1

            for mailingHistory in mailingHistories:

                if mailingHistory.mailing_date < today and (diff == -1 or (today - mailingHistory.mailing_date) < diff):

                    mostRecentHistory = mailingHistory
                    diff = today - mostRecentHistory.mailing_date

            if mostRecentHistory is None:
                return "No Mailing History"
            else:
                return mostRecentHistory.mailing_date
        else:
            return "No Mailing History"


    most_recent_mailing_date.admin_order_field = 'self.most_recent_mailing_date'

我要订购的字段是 most_recent_mailing_date。 这是一个自定义字段。 有可能吗?

提前致谢!

【问题讨论】:

  • 从 Django 2.1 开始,您可以使用表达式按 admin_order_by 中的自定义/非 DB 字段进行排序,但我不明白该怎么做!不确定此评论是否会使这更相关,因为 Django 2+ 仅在 Python 3+ 上运行...

标签: python django python-2.7 django-admin


【解决方案1】:

我认为这是不可能的。来自docs

您有四个可用于 list_display 的可能值:

....

表示模型属性的字符串。这表现得几乎 与可调用对象相同,但在这种情况下,自我是模型 实例。这是一个完整的模型示例:

from django.db import models from django.contrib import admin

class Person(models.Model):
    name = models.CharField(max_length=50)
    birthday = models.DateField()

    def decade_born_in(self):
        return self.birthday.strftime('%Y')[:3] + "0's"
    decade_born_in.short_description = 'Birth decade'

class PersonAdmin(admin.ModelAdmin):
    list_display = ('name', 'decade_born_in')

因此,您的字段是第四个选项。然而:

关于 list_display 需要注意的几个特殊情况:

...

通常,list_display 的元素不是实际的数据库字段 不能用于排序(因为 Django 在 数据库级别)。

...(继续描述此处不适用的异常)。

因此,您只能对实际的数据库字段进行排序。

【讨论】:

    【解决方案2】:

    您不能使用 Django 的order_by,因为它是在数据库级别应用的。数据库对您的 python 方法和属性一无所知。

    但是,您可以在 Python 中进行排序

    objects = MyModel.objects.all()
    sorted(objects, key=lambda k: k.most_recent_mailing_date())
    

    如果你想要逆序,

    objects = MyModel.objects.all()
    sorted(objects, key=lambda k: k.most_recent_mailing_date(), reverse=True)
    

    建议

    • 我认为您应该在返回类型上保持一致。如果没有邮寄历史记录,您可以返回一些旧日期而不是返回字符串。

    • 我认为您应该考虑在 most_recent_mailing_date() 上使用 @property 装饰器,这样您就可以简单地将其称为 instance.most_recent_mailing_date。这将使您在引用实际模型字段的方式上保持一致。

    【讨论】:

      猜你喜欢
      • 2022-10-05
      • 1970-01-01
      • 1970-01-01
      • 2021-12-14
      • 1970-01-01
      • 2014-07-12
      • 2020-01-10
      • 2016-04-21
      • 2014-07-21
      相关资源
      最近更新 更多