Django管理动态表单字段填充

时间:2016-04-15 08:51:22

标签: django django-models django-forms django-admin custom-fields

我在Gameonomy模型上有ManyToMany关系的Game模型有多种类型(PLATFORM,GENRE,FEATURE等)

class Game(models.Model):
    taxonomy = models.ManyToManyField(Taxonomy)

class Taxonomy(models.Model):
    TAXONOMY_ORDER = [
        'PLATFORM',
        'GAME_PROCESS',
        'GRAPHICS',
        'GENRE',
        'CATEGORY',
        'FEATURE'
    ]
    type = models.CharField(choices=TAXONOMY_TYPES.items(), max_length=15)

我想从管理员中删除taxonomy字段,并为TAXONOMY_ORDER

中的每种分类法类型添加单独的MultiplueChoises字段
class GameAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(GameAdminForm, self).__init__(*args, **kwargs)
        taxonomy_active = kwargs['instance'].taxonomy.all().values_list('id', flat=True)

        for tax_type in Taxonomy.
            self.fields['taxonomy_' + tax_type] = forms.MultipleChoiceField()
            self.fields['taxonomy_' + tax_type].queryset = Taxonomy.objects.filter(type=tax_type)
            self.Meta.fields.append('taxonomy_' + tax_type)
            self.initial['taxonomy' + tax_type] = Taxonomy.objects.filter(
                                                    id__in=taxonomy_active,
                                                    type=tax_type
                                                ).values_list('id', flat=True)

class GameAdmin(admin.ModelAdmin):
    form = GameAdminForm

    def get_fieldsets(self, request, obj=None):
        fieldsets = super(GameAdmin, self).get_fieldsets(request, obj)

        for tax_type in Taxonomy.TAXONOMY_ORDER:
            fieldsets[0][1]['fields'] += ['taxonomy_' + tax_type]

        return fieldsets

我有两个问题:

  1. 当我尝试动态添加字段时,我收到错误

    Unknown field(s) (taxonomy_FEATURE, taxonomy_PLATFORM, taxonomy_CATEGORY, taxonomy_GRAPHICS, taxonomy_GENRE, taxonomy_GAME_PROCESS) specified for Game. Check fields/fieldsets/exclude attributes of class GameAdmin.
    
  2. 当我尝试明确添加自定义字段时,它们会呈现空白

    class GameAdminForm(forms.ModelForm):
        taxonomy_PLATFORM = forms.MultipleChoiceField()
        taxonomy_GAME_PROCESS = forms.MultipleChoiceField()
        taxonomy_GRAPHICS = forms.ChoiceField()
        taxonomy_GENRE = forms.MultipleChoiceField()
        taxonomy_CATEGORY = forms.MultipleChoiceField()
        taxonomy_FEATURE = forms.MultipleChoiceField()
    
        def __init__(self, *args, **kwargs):
            ***__init__ stuff***
    

2 个答案:

答案 0 :(得分:0)

我发现使用数据解决动态MultipleChoiceField填充问题很热,但仍在寻找向ModelForm添加自定义动态字段的正确解决方案。

  1. 要使用现有值填充MultipleChoiceField,我们需要在初始化时传递choises

    forms.MultipleChoiceField(choices=choises)
    
  2. 要以动态方式执行此操作,我们需要将字段添加到self.fields

    中的__init__
    self.fields['dynamic_field_name'] = forms.MultipleChoiceField(choices=choises)
    
  3. 传递selected值:

    self.initial['dynamic_field_name'] = initial_value
    
  4. 完整代码:

    class GameAdminForm(forms.ModelForm):
        dynamic_field = forms.MultipleChoiceField()
    
        def __init__(self, *args, **kwargs):
            super(GameAdminForm, self).__init__(*args, **
    
    
            choises = Taxonomy.objects.all().values_list('id', 'name')
            self.fields['dynamic_field'] = forms.MultipleChoiceField(choices=choises)
            self.initial['dynamic_field'] = active_id_list
    
        class Meta:
            model = Game
            fields = '__all__'
    
    
    class GameAdmin(admin.ModelAdmin):
        form = GameAdminForm
        exclude = ['rating', '_id']
    
    admin.site.register(Game, GameAdmin)
    

答案 1 :(得分:0)

我没有代表发表评论,所以这必须是一个答案。我一直试图为自己的项目解决同样的问题,我找到的最好的解决方案是chadgh这个自我回答的问题:How do I create and save dynamic fields in Django ModelAdmin?

我在我的代码中尝试过这种方法。它完美地工作,我认为它完全符合你想要完成的任务。唯一需要注意的是

def get_form(self, request, obj=None, **kwargs):
    kwargs['fields'] = flatten_fieldsets(self.declared_fieldsets)
    return super(PersonAdmin, self).get_form(request, obj, **kwargs)
从Django 1.7开始,不推荐使用

self.declared_fieldsets。我使用self.fieldsets代替它,它运行良好。

主要的困难是ModelAdmin通常在表单的__init__执行之前,在实例化之前从表单类中获取字段,因此它不会看到动态字段。这就是你必须覆盖ModelAdmin.get_form

的原因