Using Django CreateView to process a formset - it doesn't validate
I am trying to change the view of the CreateView class to handle a set of forms instead of a form.
When the client makes a GET request, the format is displayed to the client correctly. The problem is that the client is submitting the form using POST.
When Django receives a POST, it lands at form_invalid () and form.errors says that this field is needed for the length and name field.
class Service(models.Model): TIME_CHOICES = ( (15, '15 minutes'), (30, '30 minutes'), ) length = models.FloatField(choices=TIME_CHOICES,max_length=6) name = models.CharField(max_length=40) class ServiceForm(ModelForm): class Meta: model = Service ServiceFormSet = modelformset_factory(Service,form=ServiceForm) class ServiceEditView(CreateView): template_name = "service_formset.html" model = Service form_class = ServiceForm success_url = 'works/' def form_valid(self, form): context = self.get_context_data() formset = context['formset'] if formset.is_valid(): self.object = form.save() return HttpResponseRedirect('works/') else: return HttpResponseRedirect('doesnt-work/') def form_invalid(self, form): print form.errors return HttpResponseRedirect('doesnt-work/') def get_context_data(self, **kwargs): context = super(ServiceEditView, self).get_context_data(**kwargs) if self.request.POST: context['formset'] = ServiceFormSet(self.request.POST) else: context['formset'] = ServiceFormSet(queryset=Service.objects.filter(user__exact=self.request.user.id)) return context
How can I use createview to handle a set of forms? What am I missing to make sure this is validated correctly?
In the tutorial, I took most of the bits from http://haineault.com/blog/155/
In short, what I have done so far
Since the variable form.errors says that every field is required, I think it is expecting a regular form and not a form -> I am missing any option that tells CreateView this is a set of forms.
I've also tried the solution suggested here: http://www.kevinbrolly.com/ .
class BaseServiceFormSet(BaseModelFormSet): def __init__(self, *args, **kwargs): super(BaseServiceFormSet, self).__init__(*args, **kwargs) for form in self.forms: form.empty_permitted = False
But that didn't matter.
source to share
pip install django-extra-views
And in view.py:
from extra_views import FormSetView class ItemFormSetView(ModelFormSetView): model = Service template_name = 'service_formset.html'
There is a discussion about how to do this in Django core, but the discussions seem to have stalled. https://code.djangoproject.com/ticket/16256
Where I found the solution
This repository https://github.com/AndrewIngram/django-extra-views has a view called ModelFormSetView that does exactly what I need. It's a class-based view that does the same thing as CreateView, but for forms.
source to share
Django go to form_invalid () and form.errors says this field is needed for length and name field.
This is ok and because of the required paramatere field :
By default, every Field class assumes that this value is needed, so if you pass in an empty value - either None or an empty string ("") - then clean () will throw a ValidationError exception:
If you want to reverse this, you can set required = False :
class Service(models.Model): TIME_CHOICES = ( (15, '15 minutes'), (30, '30 minutes'), ) length = models.FloatField(choices=TIME_CHOICES,max_length=6, required=False) name = models.CharField(max_length=40, required=False)
What am I missing to make sure this is validated correctly
Have you tried to post a form with names and .
source to share