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.

+3


source to share


2 answers


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.

+6


source


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 .

0


source







All Articles