Using Django CreateView to process a formset - it doesn't validate
Problem
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
My question
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
Decision
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