2015-09-01 61 views
0

我有一些型號:如何在Django ModelAdmin中創建和保存動態字段?

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

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

class Person(models.Model): 
    name = models.CharField(max_length=255) 
    groups = models.ManyToManyField(Group, related_name="+") 

但在的ModelAdmin我想動態添加字段每個組的類型。所以,如果我有兩個組類型public,private,我希望管理員表單顯示兩個字段public_groupsprivate_groups而不是實際的數據庫字段groups

更多信息

我試圖創建一個自定義窗體動態添加字段:

class PersonAdminForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(PersonAdminForm, self).__init__(*args, **kwargs) 
     new_fields = {} 
     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_field = forms.ModelMultipleChoiceField(queryset=qs) 
      new_fields[field_name] = field_field 
     self.fields.update(new_fields) 

    class Meta: 
     model = Person 
     fields = '__all__' 

這似乎就這樣的伎倆如添加字段的形式。但保存這些字段並將它們添加到PersonAdmin不起作用。如果我明確地將字段添加到fields屬性上PersonAdmin我得到:

def get_fieldsets(self, request, obj=None): 
    fieldsets = super(PersonAdmin, self).get_fieldsets(request, obj) 
    print(self.form.fields) 
    fieldsets[0][1]['fields'].extend(['public_groups', 'private_groups']) 
    return fieldsets 

回答

0

FieldError: Unknown field(s) (public_groups, private_groups) specified for Person. Check fields/fieldsets/exclude attributes of class PersonAdmin. 

試圖將它們加入到「動態」通過定製get_formsets方法時,我也得到了同樣的事情以下代碼完美運行。 ModelForm上覆蓋的__init__clean方法添加動態字段並定義應如何保存值。

的覆蓋get_formget_fieldsets與上AdminModelfieldsets屬性一起確保動態表單字段將會顯示在管理員。

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 
相關問題