【问题标题】:Add dynamic field to django admin model form将动态字段添加到 django 管理模型表单
【发布时间】:2014-08-05 23:34:51
【问题描述】:

我需要将带有指向我网站上模型视图的链接的字段添加到 django 管理视图。 当我将字段名称添加到 list_display 并定义呈现此 url 的方法时:

class SetAdmin(admin.ModelAdmin):
    list_display = ['many other fields', 'show_set_url']

    def show_set_url(self, obj):
            return '<a href="#">Set</a>' # render depends on other fields

它显示在 django admin 的 Sets 列表中,但不以模型形式显示。 如何解决这个问题并在 django admin 中添加指向 Sets Form 的链接?

我也尝试为这个模型创建自定义表单:

from core.models import Set
from django import forms

class SetAdminForm(forms.Form):
    class Meta:
        model = Set

    def __init__(self, *args, **kwargs):
        super(SetAdminForm, self).__init__(*args, **kwargs)
        self.fields['foo'] = forms.IntegerField(label=u"Link")

但现在形式上有明显的效果。

【问题讨论】:

  • 不,现在我得到 KeyError: "Key u'show_set_url' not found in Form"

标签: python django


【解决方案1】:

您可以通过覆盖ModelAdmin 来完成您正在尝试的操作,但您还需要覆盖ModelAdmin.get_fieldsetsThis 答案可能会帮助你。链接中的 OP 也有类似的问题。

编辑:如果您不想要可编辑的字段,您可以尝试覆盖 ModelAdmin.get_readonly_fields。还要检查here 以获取更多要覆盖的属性。

【讨论】:

  • 是的,像这样。但我得到了一个可编辑的字段,我需要它作为可点击的链接。如何将其呈现为链接?
  • 覆盖 ModelAdmin.get_readonly_fields 应该这样做。您可以查看here 以获取可覆盖属性的完整列表。
【解决方案2】:

您可以使用表单元类创建动态字段和字段集。示例代码如下。根据您的要求添加循环逻辑。

class CustomAdminFormMetaClass(ModelFormMetaclass):
    """
    Metaclass for custom admin form with dynamic field
    """
    def __new__(cls, name, bases, attrs):
        for field in myloop: #add logic to get the fields
            attrs[field] = forms.CharField(max_length=30) #add logic to the form field
        return super(CustomAdminFormMetaClass, cls).__new__(cls, name, bases, attrs)


class CustomAdminForm(six.with_metaclass(CustomAdminFormMetaClass, forms.ModelForm)):
    """
    Custom admin form
    """

    class Meta:
        model = ModelName
        fields = "__all__" 


class CustomAdmin(admin.ModelAdmin):
    """
    Custom admin 
    """

    fieldsets = None
    form = CustomAdminForm

    def get_fieldsets(self, request, obj=None):
        """
        Different fieldset for the admin form
        """
        self.fieldsets = self.dynamic_fieldset(). #add logic to add the dynamic fieldset with fields
        return super(CustomAdmin, self).get_fieldsets(request, obj)

    def dynamic_fieldset(self):
        """
        get the dynamic field sets
        """
        fieldsets = []
        for group in get_field_set_groups: #logic to get the field set group
            fields = []
            for field in get_group_fields: #logic to get the group fields
                fields.append(field)

            fieldset_values = {"fields": tuple(fields), "classes": ['collapse']}
            fieldsets.append((group, fieldset_values))

        fieldsets = tuple(fieldsets)

        return fieldsets

【讨论】:

  • 这个答案对我帮助很大,我稍微改了一下,只需要重写get_readonly_fields方法,谢谢!
【解决方案3】:

您必须将其添加到readonly_fields 列表中。

class SetAdmin(admin.ModelAdmin):
    list_display = ['many other fields', 'show_set_url']
    readonly_fields = ['show_set_url']

    def show_set_url(self, obj):
            return '<a href="#">Set</a>' # render depends on other fields

Relevant documentation.

【讨论】:

    【解决方案4】:

    对于内联模型,我在 Django 1.9 中遇到了所有这些问题。

    这是一个为我完成动态字段的代码 sn-p。在此示例中,我假设您已经有一个名为 ProductVariant 的模式,其中包含与名为 Product 的模型的外键关系:

    class ProductVariantForm(forms.ModelForm):
      pass
    
    class ProductVariantInline(admin.TabularInline):
      model = ProductVariant
      extra = 0
    
      def get_formset(self, request, obj=None, **kwargs):
        types = ( (0, 'Dogs'), (1, 'Cats'))
            #Break this line appart to add your own dict of form fields.
            #Also a handy not is you have an instance of the parent object in obj
        ProductVariantInline.form = type( 'ProductVariantFormAlt', (ProductVariantForm, ), { 'fancy_select': forms.ChoiceField(label="Animals",choices=types)})
        formset = super( ProductVariantInline, self).get_formset( request, obj, **kwargs)
        return formset
    
    class ProductAdmin(admin.ModelAdmin):
      inlines = (ProductVariantInline, )
    

    我的具体用例是 ProductVariant 具有多对多关系,该关系应该仅具有基于条目的业务逻辑分组的有限选择。因此我需要内联中的自定义动态字段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-14
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 1970-01-01
      • 2012-06-05
      • 1970-01-01
      • 2019-06-17
      相关资源
      最近更新 更多