来自两个表的 django admin list_display,没有可用的外键或多对多关系

django admin list_display from two tables, no relations like foreign key or manytomany relation available

我有两个表,一个是 MeasuredController 和 MeasuredGrid,没有外键或 manytoman 等关系,在管理中我必须显示 MeasuredGrid 的两个字段,即 power 和 status,其中 MeasuredController 的 senddate = MeasuredGrid 的 senddate ,在两个不同的专栏中,我写了如下代码,但在当前代码中,每个对象都会访问数据库两次,所以有没有像 select 相关的方法或使用缓存概念?

list_display = ("grid_status", "grid_power")

def grid_status(self, obj):
    STATUS_CHOICES = {0:"Outage", 1:"No Outage" }
    mobj = MeasuredGrid.objects.filter(senddate=obj.senddate).latest("senddate")

    try:
        return STATUS_CHOICES[int(mobj.status)], 2
    except:
        pass
grid_status.short_description = 'Grid Status'

def grid_power(self, obj):
    mobj = MeasuredGrid.objects.filter(senddate=obj.senddate).latest("senddate")
    return mobj.power

grid_power.short_description = 'Grid Power[W]'

您可以使用 Cache Framework。非常简单:

# coding: utf-8
from django.core.cache import cache
from django.contrib import admin

from .models import MeasuredController, MeasuredGrid


class MeasuredControllerAdmin(admin.ModelAdmin):
    list_display = ("grid_status", "grid_power")

    STATUS_CHOICES = {
        0: "Outage",
        1: "No Outage",
    }

    def grid_status(self, obj):
        mobj = self._get_mobj_data(obj)
        return mobj['status']
    grid_status.short_description = 'Grid Status'

    def grid_power(self, obj):
        mobj = self._get_mobj_data(obj)
        return mobj['power']
    grid_power.short_description = 'Grid Power[W]'

    def _get_mobj_data(self, obj):
        """Get a relevant MeasuredGrid object for a given MeasuredController"""

        data = cache.get('mobj_%s' % obj.pk)
        if data is not None:
            return data

        mobj = MeasuredGrid.objects.filter(senddate=obj.senddate).latest("senddate")

        status = None
        try:
            status = self.STATUS_CHOICES[int(mobj.status)], 2
        except: # <---------- Not the best decision. You probably need ValueError or KeyError
            pass

        data = {
            "id": mobj.pk,
            "power": mobj.power,
            "status": status,
        }

        cache.set('mobj_%s' % obj.pk, data) # the default timeout is 300 seconds

        return data

注意: 默认的缓存后端是 django.core.cache.backends.locmem.LocMemCache,所以即使在开发环境中缓存也可以工作(即 DEBUG = True)。