Django admin自定义字段按条件获取最新相关对象的结果

标签 django django-admin django-queryset django-aggregation django-annotate

我有三个模型

class Customer(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    # some other fields, which don't matter

class ActivityStatus(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    name = models.CharField(max_length=5)

class Activities(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    status = models.ForeignKey(ActivityStatus)
    planned_execution_date = models.DateField()

我在管理员里也有两个

class CustomerAdmin(admin.ModelAdmin):
    fields = () # doesn't matter really
    list_display() # doesn't matter really

class ActivityAdmin(admin.ModelAdmin):
    fields = () # doesn't matter really
    list_display() # doesn't matter really

我想添加自定义字段 (last_activity_planned_date) 以在 CustomerAdmin 的 changelist_view 上显示和排序。这是条件: - 显示客户最新事件的计划执行日期,但前提是该事件的 status_id = 2。否则什么都不显示

示例 1

客户 1 有 2 个事件 - 最新的有 status_id = 2 和 planned_execution_date = 2017-09-17

变更 ListView :

|id|last_activity_planned_date|

|1|2017-09-17|

示例 2

客户 1 有 2 个事件 - 最新的事件有 status_id = 3 和 planned_execution_date = 2017-09-27

|id|last_activity_planned_date|

|1|空|

最佳答案

您可以添加 custom fields in list_display :

class CustomerAdmin(admin.ModelAdmin):
    fields = () 
    list_display = ('last_activity_planned_date',)

    def last_activity_planned_date(self, obj):
        latest_activity = obj.activities.order_by('-planned_execution_date').first()
        if latest_activity and latest_activity.status_id == 2:
            return latest_activity.planned_execution_date
        else:
            return None

但是,要使该列可排序,这将非常复杂。即使在原始 SQL 中,它看起来也是一个复杂的查询。在 Django 2.1 中添加了对 admin_order_field 中查询表达式的支持,但我仍然无法找到一个合适的 SQL 查询来实现这种排序。

解决方案是在字段 Customer.last_activity_planned_date 中复制此信息(使用 db_index=True 以提高订购性能)。

如果您负担得起仅定期更新此信息,您可以设置一个 cronjob 以每 1500 万、1 小时或 1 天更新一次(根据您的需要和进行更新所需的资源)。

如果您需要此信息始终准确无误,则每次创建、更新或删除 Activities 条目时都必须更新它。根据您的需要,有多种方法可以执行此操作,包括 SQL triggersDjango signals .这工作得很好,但不是百分百确定,所以即使你使用这个解决方案,我还是建议设置一个每日 cronjob 以确保所有数据都是一致的。

关于Django admin自定义字段按条件获取最新相关对象的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52637110/

相关文章:

python - django - 将现有的 ModelAdmin 及其内联添加到另一个管理表单

python - 如何从 django admin 中的单个 "Choose Files"选择器上传多张图片

json - 我的 Django View 如何知道要呈现哪个模板,或者是否返回 JSON?

python - 在 Django 中登录管理员

django - 从 ModelForm 的 FileField 保存文件

django - 在每个查询中查询同一字段的多个模型

python - 将 Django 模型传递给模板

python - Graphene-Django 嵌套过滤器(中继)

python - 我可以在没有 ORM 的情况下从 Django 查询辅助数据库吗?

OnetoOneField 的 Django 订单查询集