Django:伪造管理界面中的字段?

Nic*_*ner 14 python django django-admin

我有一个模特,Foo.它具有多个数据库属性,以及基于多个因素组合计算的多个属性.我想将这些计算出的属性呈现给用户,就好像它们是数据库属性一样.(支持因素将被更改以反映用户输入.)有没有办法使用Django管理界面?

Rei*_*cke 30

我建议你为Foo(FooAdminForm)子类化一个modelform来添加你自己的数据库没有支持的字段.您的自定义验证可以驻留在clean_*ModelForm 的方法中.

里面save_model的方法,FooAdmin你的要求,实例Foo和形式的数据,所以你可以保存实例之后,做前/后的所有数据处理.

以下是使用django admin注册的自定义表单的模型示例:

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


class Foo(models.Model):
    name = models.CharField(max_length=30)


class FooAdminForm(forms.ModelForm):
    # custom field not backed by database
    calculated = forms.IntegerField()

    class Meta:
        model = Foo 


class FooAdmin(admin.ModelAdmin):
    # use the custom form instead of a generic modelform
    form = FooAdminForm

    # your own processing
    def save_model(self, request, obj, form, change):
        # for example:
        obj.name = 'Foo #%d' % form.cleaned_data['calculated'] 
        obj.save()


admin.site.register(Foo, FooAdmin)
Run Code Online (Sandbox Code Playgroud)

根据实例数据提供自定义字段的初始值

(我不确定这是否是最佳解决方案,但它应该有效.)

当构造数据库中现有模型实例的模型时,它将传递给该实例.因此,在FooAdminForm中,__init__可以根据实例数据更改字段属性.

    def __init__(self, *args, **kwargs):
        # only change attributes if an instance is passed            
        instance = kwargs.get('instance')
        if instance:
            self.base_fields['calculated'].initial = (instance.bar == 42)
        forms.ModelForm.__init__(self, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)


Chr*_*att 5

获取任意数据以显示在更改列表中或使字段显示在表单中很容易:list_display任意采用实际模型属性,或在模型或模型管理员上定义的方法,您可以子类化forms.ModelForm以添加您想要的任何字段类型想换个表格。

更困难/不可能的是将两者结合起来,即在更改列表中有任意一段数据,您可以通过指定list_editable. Django 似乎只接受与数据库字段对应的真实模型属性。(即使@property在模型定义中的方法上使用也是不够的)。

有没有人找到一种方法来直接从更改列表页面编辑模型上实际上不存在的字段?

  • 我很想得到答案 (2认同)