【问题标题】:Django admin form dynamically change fields based on checkboxDjango 管理表单根据复选框动态更改字段
【发布时间】:2015-09-09 20:34:36
【问题描述】:

我正在 Django 中实现一个日历,并希望扩展我的功能并添加对重复事件的支持。我的问题是我想要一个在单日/多日事件和重复事件之间切换的 BooleanField。因此,该字段将被标记为:这是一个经常性事件吗?如果用户选中该框,它会更改开始和结束字段以显示不同的字段。

这是我的model.py的简短版本

class Event(models.Model):

    title = models.CharField(max_length=40)

    description = models.TextField(blank=True)

    is_recurring = models.BooleanField(blank=True, default=False, verbose_name='Event is recurring?')

    start = models.DateTimeField()

    end = models.DateTimeField()    

    def __str__(self):
        return self.title

如果用户检查 is_recurring 字段,则动态删除这 2 个字段并更改表单。这是我的 admin.py:

class EventAdmin(admin.ModelAdmin):
    form = EventForm
    fieldsets = [
        (None,  {'fields': [
                                'title',
                                'description'
                            ]
                }
        ),
        (None,  {'fields':  [
                                'is_recurring',
                                'start',
                                'end',
                            ]
                }
        ),
    ]   # END fieldset

    def get_fieldsets(self, *args, **kwargs):
        return(
                (None, {
                        'fields' : ('my_extra_field',),
                    }),
            )

admin.site.register(Event , EventAdmin)

这是我的forms.py

class EventForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(EventForm, self).__init__(*args, **kwargs)
        self.fields['my_extra_field'] = forms.CharField()

    class Meta:
        model = Event

所以我在这里尝试将my_extra_field 添加到表单中,尝试一下,但我不断收到

为事件指定了未知字段 (my_extra_field)。查看 类 EventAdmin 的字段/字段集/排除属性。

并且无法找到检索我的字段的方法。我有一种印象,可能是因为我使用的是fieldsets,您可能想建议不要使用它,但不幸的是,我从模型中删除了很多信息,以使其更适合问题,因此我需要使用fieldsets

所以为了完成我的问题,我想知道如何在我的复选框上动态添加一个字段?作为问题的扩展,如何从我的表单中删除 2 个字段?

【问题讨论】:

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


    【解决方案1】:

    额外的字段必须存在于表单中,以便您可以在字段集中使用它:

    class EventForm(forms.ModelForm):
        my_extra_field = forms.CharField()   
    
        class Meta:
            model = Event
            exclude = tuple()  # Required in recent Django versions.
                               # Be careful not to include fields by accident.
    

    您可能必须覆盖表单上的save(),因为ModelForm 不知道如何处理您的额外字段。

    class EventForm(forms.ModelForm):
        my_extra_field = forms.CharField()
    
        def save(self, *args, **kwargs):
            if self.cleaned_data['is_recurring']:
                # do something with your extra fields,
                # remove values from other fields, etc.
            super(EventForm, self).save(*args, **kwargs)
    

    如果您想在不重新加载页面的情况下更改表单,则需要使用 Javascript。

    【讨论】: