Django - 使表单记住复选框值

1 投票
2 回答
2236 浏览
提问于 2025-04-18 15:34

我来用一个基本的设置来回答这个问题:

# models.py
class MyModel(models.Model):
    required_field = models.CharField("some label", max_length=10)
    another_required_field = models.CharField("some label", max_length=10)
    checkbox = models.BooleanField("some label")

# forms.py
class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel

# views.py
class MyView(FormView):
    form_class = MyForm
    template_name = 'some-template.html'

假设我勾选了复选框,并且只填写了一个必填字段。显然,表单没有通过验证,返回了一堆错误信息。问题是,复选框的值又变成了未勾选。这对于只有一个布尔字段的情况来说还好,但我正在做一个项目,有很多复选框。每次都要从头开始勾选这些复选框,真让人沮丧。

所以我查了一下django的文档,发现了关于布尔字段的这一段:

Since all Field subclasses have required=True by default, the validation condition here    
is important. If you want to include a boolean in your form that can be either True or 
False (e.g. a checked or unchecked checkbox), you must remember to pass in 
required=False when creating the BooleanField.

然后我做了这个:

# forms.py
class MyForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        for field in self.fields:
            if isinstance(field, forms.CheckboxInput):
                self.fields[field].required = False
    class Meta:
        model = MyModel

但没有成功。再次强调,表单没有通过验证后,复选框会失去状态,所以我想这可能不是我想要的解决办法。

所以我的问题是,有没有办法解决这个问题?我相信应该有办法,如果有人能给我指个方向就太好了。谢谢 :-)

编辑
经过一番调试,我解决了这个问题。原来我在使用自定义模板来处理crispy表单的复选框时,发现里面有个小bug。

2 个回答

0

你的视图需要从 request.POST 字典中填充表单,像这样:

def your_view(request):
    form = MyForm(request.POST or None)
    if request.method == 'POST' and form.is_valid():
        form.save()
        # do whatever esle

    return render(request, 'your-template.html', {'form': form})

如果你不传递 request.POST 数据,或者你正在编辑的模型实例,你的表单就会是“未绑定”的,这样就不会显示任何在 POST 数据中或模型中存在的值。如果你是在编辑一个实例,它看起来会像这样:

def your_view(request, id):
    my_model_instance = MyModel.objects.get(pk=id)
    form = MyForm(request.POST or None, instance=my_model_instance)
    if request.method == 'POST' and form.is_valid():
        form.save()
        # do whatever esle

    return render(request, 'your-template.html', {'form': form})
0

可能问题出在你的视图上:

视图示例:

def view(request):

if request.method == 'POST':#bound the form wit data from request.Post
    form = MyForm(request.POST)

    if form.is_valid():
        #do somthing
        form.save()
    #if form not valid render the page.html with form that  has request.Post data 
    return render(request,'some-template.html',{'form': form})

else:
    form = MyForm()
    return render(request, 'some-template.html',{'form': form})

撰写回答