Django 管理动态表单字段填充
Django admin dynamic form fields population
我的游戏模型在分类模型上具有 ManyToMany 关系 有多种类型(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
我有两个问题:
当我尝试动态添加字段时收到错误
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.
当我尝试显式添加自定义字段时,它们呈现为空白
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***
我发现用数据解决动态 MultipleChoiceField 填充很热门,但仍在寻找将自定义动态字段添加到 ModelForm 的合适解决方案。
要使用现有值填充 MultipleChoiceField,我们需要在初始化时传递 choises
:
forms.MultipleChoiceField(choices=choises)
要以动态方式做到这一点,我们需要将我们的字段添加到 __init__
中的 self.fields
self.fields['dynamic_field_name'] = forms.MultipleChoiceField(choices=choises)
传递selected
值:
self.initial['dynamic_field_name'] = initial_value
完整代码:
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)
我没有评论代表,所以这必须是一个答案。我一直在尝试为我自己的项目解决同样的问题,我找到的最好的解决方案是 chadgh 的这个自我回答的问题:.
我已经在我的代码中尝试过这种方法。它工作得很好,我认为它完全符合您的要求。唯一需要注意的是
def get_form(self, request, obj=None, **kwargs):
kwargs['fields'] = flatten_fieldsets(self.declared_fieldsets)
return super(PersonAdmin, self).get_form(request, obj, **kwargs)
self.declared_fieldsets
从 Django 1.7 开始被弃用。我改用 self.fieldsets
并且效果很好。
主要困难是 ModelAdmin 通常在实例化之前从表单 class 中获取字段,在表单的 __init__
执行之前,因此它看不到动态字段。这就是为什么你必须覆盖 ModelAdmin.get_form
.
我的游戏模型在分类模型上具有 ManyToMany 关系 有多种类型(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
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
我有两个问题:
当我尝试动态添加字段时收到错误
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.
当我尝试显式添加自定义字段时,它们呈现为空白
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***
我发现用数据解决动态 MultipleChoiceField 填充很热门,但仍在寻找将自定义动态字段添加到 ModelForm 的合适解决方案。
要使用现有值填充 MultipleChoiceField,我们需要在初始化时传递
choises
:forms.MultipleChoiceField(choices=choises)
要以动态方式做到这一点,我们需要将我们的字段添加到
中的__init__
self.fields
self.fields['dynamic_field_name'] = forms.MultipleChoiceField(choices=choises)
传递
selected
值:self.initial['dynamic_field_name'] = initial_value
完整代码:
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)
我没有评论代表,所以这必须是一个答案。我一直在尝试为我自己的项目解决同样的问题,我找到的最好的解决方案是 chadgh 的这个自我回答的问题:
我已经在我的代码中尝试过这种方法。它工作得很好,我认为它完全符合您的要求。唯一需要注意的是
def get_form(self, request, obj=None, **kwargs):
kwargs['fields'] = flatten_fieldsets(self.declared_fieldsets)
return super(PersonAdmin, self).get_form(request, obj, **kwargs)
self.declared_fieldsets
从 Django 1.7 开始被弃用。我改用 self.fieldsets
并且效果很好。
主要困难是 ModelAdmin 通常在实例化之前从表单 class 中获取字段,在表单的 __init__
执行之前,因此它看不到动态字段。这就是为什么你必须覆盖 ModelAdmin.get_form
.