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

Django admin form dynamically change fields based on checkbox

我正在 Django 中实现一个日历,想扩展我的功能并添加对重复事件的支持。我的问题是我想要一个在 single/multi-day 事件和重复事件之间切换的 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 添加到表单中,尝试一下,但我不断得到

Unknown field(s) (my_extra_field) specified for Event. Check fields/fieldsets/exclude attributes of class EventAdmin.

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

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

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

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。