Django内置admin管理页中自定义数据表格列

django 内置admin管理页自定义数据表格列

amdin管理页中的数据表格修改方式我这里想到了两种,在这里分享给大家。通常我们在注册模型的时候,会创建一个模型管理类,通过这个类的属性list_display来设置需要展示的字段。所以想要数据表格展示哪些列就在这个list_display变量中添加对应的数据字段名即可。下面交大家两种创建模型中没有的列并展示的方法

方法一:在模型中创建属性化方法

首先我们要知道的是,django ORM在将数据库的数据获取出来之后,是把每一条数据都实例化成对应模型类的对象的,我们看到的数据表格中的数据,实际上就是django把这些对象作为模板变量传递给django内置的表格模板,再渲染出来的。也就是说,前面提到的list_display中的元素实际上就是这些实例对象的属性,那么我直接在模型的类中添加一个方法,利用property方法属性化,不就可以直接用了么?
上代码:

# models.py

# 定义不同的设备
class MachineA(models.Model):
    class Meta:
        verbose_name = "A设备"

    name = models.CharField("设备名称",max_length=90)

    def __str__(self):
        return self.name


class MachineB(models.Model):
    class Meta:
        verbose_name = "B设备"

    name = models.CharField("设备名称",max_length=90)

    def __str__(self):
        return self.name


# 定义设备任务
class MachineOrder(models.Model):
    class Meta:
        verbose_name = "设备工作任务"

    machine_type = models.CharField("设备类型",max_length=1,choices=(("A","A设备"),("B","B设备")))
    machine_ID = models.IntegerField("设备ID")
    order_name = models.CharField("任务名称",max_length=90)
    start_time = models.DateTime("任务开始时间")

    # 属性化方法
    @property
    def get_machine(self):
        if self.machine_type == "A":
            this_machine = MachineA.objects.get(id=self.machine_ID)
        else:
            this_machine = MachineB.objects.get(id=self.machine_ID)
        return str(this_machine)
# admin.py

# 模型注册
@admin.register(MachineOrder)
class MachineOrderAdmin(admin.ModelAdmin):
    # 使用模型原本就有的字段作为列
    # list_display = ["machine_type","machine_ID","order_name","start_time"]
    # 使用自定义的方法作为列
    list_display = ["machine_type","get_machine","order_name","start_time"]

前后效果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里有一个弊端,就是数据表格显示的列名直接就是模型的方法名,而且不能像真正字段那样添加verbose_name参数来设置名称。想要设置自定义列的列名就只有使用第二种方法

第二种方法:模型注册类中添加方法

# 模型注册
@admin.register(MachineOrder)
class MachineOrderAdmin(admin.ModelAdmin):
    # 使用模型原本就有的字段作为列
    # list_display = ["machine_type","machine_ID","order_name","start_time"]
    # 使用自定义的方法作为列
    # list_display = ["machine_type","get_machine","order_name","start_time"]

    # 使用当前管理类中的方法作为列
    list_display = ["machine_type","get_machine_func","order_name","start_time"]

    # 自定义一个方法,新的列的值就是这个方法的返回值
    def get_machine_func(self,instance):
        """
        参数:
        instance        模型的实例对象
        """
        this_type = instance.machine_type
        this_machine_id = instance.machine_ID

        if this_type == "A":
            this_machine = MachineA.objects.get(id=this_machine_id)
        else:
            this_machine = MachineB.objects.get(id=this_machine_id)

        return str(this_machine)

    # 自定义列名
    get_machine_func.short_description = "设备"

效果:
在这里插入图片描述

上面这种方法在admin页面展示时就是有中文列名的,列名也是我们自己定义的。换成pandas的代码可能更容易理解一些:

# apply里映射的函数就是我们定义的新列取值的方法,大致就是这个意思。最后得到的效果是一样的
df["get_machine_func"] = df.apply(lambda df:get_machine_func(instance=df),axis=1)
df.rename(columns={"get_machine_func":"设备"},inplace=True)

当然,如果有多个表使用的相同的列,获取值的逻辑也是一样的,那么也可以扩展一下这个方法抽取出来。

def get_machine_function(self,instance):
    this_type = instance.machine_type
        this_machine_id = instance.machine_ID

        if this_type == "A":
            this_machine = MachineA.objects.get(id=this_machine_id)
        else:
            this_machine = MachineB.objects.get(id=this_machine_id)

        return str(this_machine)

# 模型注册
@admin.register(MachineOrder)
class MachineOrderAdmin(admin.ModelAdmin):
    # 使用模型原本就有的字段作为列
    # list_display = ["machine_type","machine_ID","order_name","start_time"]
    # 使用自定义的方法作为列
    # list_display = ["machine_type","get_machine","order_name","start_time"]

    # 使用当前管理类中的方法作为列
    list_display = ["machine_type","get_machine_func","order_name","start_time"]

    # 自定义列
    get_machine_func = get_machine_function
    get_machine_func.short_description = "设备"
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值