Django 管理表单根据复选框动态更改字段

Phi*_*her 5 django django-models django-forms django-admin

我正在 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
Run Code Online (Sandbox Code Playgroud)

如果用户检查 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)
Run Code Online (Sandbox Code Playgroud)

这是我的 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Ren*_*erg 4

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

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.
Run Code Online (Sandbox Code Playgroud)

您可能必须覆盖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)
Run Code Online (Sandbox Code Playgroud)

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