I'll address this question using a base setup:
# 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'
Now suppose I check the checkbox and fill just one of the required fields. The form obviously doesn't pass validation and gets back with errors and all. Problem is, the value of the checkbox comes back unchecked. This is not a big deal with just one BooleanField, but I'm working on a project where I have tons of checkboxes. Check them all from scratch is rather frustrating. So I had a check on django's documentation and stumbled upon this paragraph regarding BooleanFields:
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.
And I did this:
# 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
but it didn't work. Again, checkboxes lose their state after the form didn't pass validation, so I guess that was not what I was looking for.
So my question is, is there a way to achieve that? I'm pretty sure there should be one, it would be great if some of you could at least drive me in the right direction. Thanks :-)
EDIT After a bit of debugging, I solved the issue. Turns out I was using a custom template for crispy forms checkboxes, and I found a little bug in there.
Your view would need to populate the form from the request.POST
dictionary as such:
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})
Unless you pass the request.POST
data, and/or an instance of the model you're editing, your form will be un-bound, and therefore not show any values that exist either in the POST data or from your model. If you're editing an instance, it would look like:
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})
maybe the problem is on your view:
view exemple:
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})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.