How do I create and save dynamic fields in Django ModelAdmin?

前端 未结 1 619
忘掉有多难
忘掉有多难 2021-01-25 02:28

I have some models:

class GroupType(models.Model):
    name = models.CharField(max_length=255)

class Group(models.Model):
    name = models.CharField(max_length         


        
相关标签:
1条回答
  • 2021-01-25 03:26

    The following code worked perfectly. The overridden __init__ and clean methods on the ModelForm adds the dynamic fields and defines how the values should be saved.

    The overridden get_form and get_fieldsets together with the fieldsets attribute on the AdminModel make sure the dynamic form fields get displayed in the admin.

    class PersonAdminForm(forms.ModelForm):
        def __init__(self, *args, **kwargs):
            super(PersonAdminForm, self).__init__(*args, **kwargs)
            new_fields = {}
            initial = self.instance.groups.all()
            for group_type in GroupType.objects.all():
                field_name = '{0}_groups'.format(group_type.name.lower())
                qs = Group.objects.filter(group_type=group_type)
                field = forms.ModelMultipleChoiceField(
                    queryset=qs,
                    required=False,
                    initial=initial,
                )
                new_fields[field_name] = field
            self.fields.update(new_fields)
    
        def clean(self):
            cleaned_data = super(PersonAdminForm, self).clean()
            groups = []
            for group_type in GroupType.objects.all():
                gt_name = '{0}_groups'.format(group_type.name.lower())
                groups.extend(cleaned_data.get(gt_name))
            self.instance.groups.clear()
            self.instance.groups.add(*groups)
            return cleaned_data
    
        class Meta:
            model = Person
            fields = '__all__'
    
    
    @admin.register(Person)
    class PersonAdmin(admin.ModelAdmin):
        form = PersonAdminForm
    
        # using the fieldsets attribute instead of fields in order to dynamically
        # add group type fields later.
        fieldsets = (
            (None, {
                'fields': (
                    'name',
                ),
            }),
        )
    
        def get_form(self, request, obj=None, **kwargs):
            kwargs['fields'] = flatten_fieldsets(self.declared_fieldsets)
            return super(PersonAdmin, self).get_form(request, obj, **kwargs)
    
        def get_fieldsets(self, request, obj=None):
            fieldsets = super(PersonAdmin, self).get_fieldsets(request, obj)
            newfieldsets = list(fieldsets)
            fields = []
            for group_type in GroupType.objects.all():
                fields.append('{0}_groups'.format(group_type.name.lower()))
            newfieldsets.append(['Groups', {'fields': fields}])
            return newfieldsets
    
    0 讨论(0)
提交回复
热议问题