Django通用模型表单集

时间:2017-12-08 15:30:59

标签: django django-models django-forms modelform formsets

所以我有一个网站,用户可以注册设备,然后向这些设备注册命令。这些命令具有关联的小部件(按钮,滑块等),用于确定命令具有的唯一属性。

我试图找出在我的应用程序中使用模型表单集的最通用方法。我有一些工作,我为每个ModelForm创建一个model_formset,并从每个模型中获取数据以放置在formset中,然后在我的模板中显示它。

我真正想做的是这样的事情:

command_formset = modelformset_factory(Command, extra=0, fields='__all__')
formset = command_formset(queryset=Command.objects.filter(device_id=device_id))

我获取所有命令(返回按钮和滑块),然后创建一个包含所有命令对象的command_formset。

在这种情况下,它会完成我正在寻找的部分内容,在那里我可以查询我的模型并获取所有按钮和滑块命令,但是formset只包含命令中的字段 - 因此滑块的最小值和最大值是丢失。

这样的事情可能吗?这是我更完整的代码:

模型

class Command(models.Model):
    command_name = models.CharField(max_length=100)
    command = models.CharField(max_length=100)
    command_url = models.CharField(max_length=100)
    command_type = models.CharField(max_length=100)
    device = models.ForeignKey(Device, on_delete=models.CASCADE, default=1)  # Each command has one device

    def __str__(self):
        return self.command_name


class ButtonCommand(Command):
    button_color = models.CharField()


class SliderCommand(Command):
    min_value = models.IntegerField()
    max_value = models.IntegerField()

表单

class CommandForm(ModelForm):
    class Meta:
        model = Command
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in iter(self.fields):
            self.fields[field].widget.attrs.update({'class': 'form-control'})


class ButtonCommandForm(ModelForm):
    class Meta:
        model = ButtonCommand
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in iter(self.fields):
            self.fields[field].widget.attrs.update({'class': 'form-control'})


class SliderCommandForm(ModelForm):
    class Meta:
        model = SliderCommand
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in iter(self.fields):
            self.fields[field].widget.attrs.update({'class': 'form-control'})

查看

command_formset = modelformset_factory(Command, extra=0, fields='__all__')
button_command_formset = modelformset_factory(ButtonCommand, form=ButtonCommandForm, extra=0,
                                              fields=('command_name', 'command', 'command_type', 'command_url'))
slider_command_formset = modelformset_factory(SliderCommand, extra=0,
                                              fields=('command_name', 'command', 'command_type', 'command_url',
                                                      'min_value', 'max_value'))

device_form = DeviceForm(initial=device)

formset = command_formset(queryset=Command.objects.filter(device_id=device_id))
button_formset = button_command_formset(queryset=ButtonCommand.objects.filter(device_id=device_id),
                                        prefix="button_form")
slider_formset = slider_command_formset(queryset=SliderCommand.objects.filter(device_id=device_id),
                                        prefix="slider_form")

修改其他观看代码

template = 'device_control/device_management.html'
return TemplateResponse(request, template, {'device': device,
                                            'device_form': device_form,
                                            'button_formset': button_formset,
                                            'slider_formset': slider_formset,
                                            'formset' : formset})

另一个相关问题

    input_type = request.POST['command_type']
    if input_type == 'button':
        form = ButtonCommandForm(request.POST)
    elif input_type == 'slider':
        form = SliderCommandForm(request.POST)
    else:
        form = None

希望我不是压倒性的,但上面是一个非常相似的问题,似乎更简单。用户发布一个表单,这两个表单都继承自Command。虽然上面的内容非常简单,但如果我最终有20多种不同类型的CommandForms,那么这将变得非常讨厌。

我真的希望我错过Django可以告诉哪些子表单应该用来构建表单的方式。

0 个答案:

没有答案