简体   繁体   中英

Django is_valid() not working with modelformset_factory

I've created a simple contact form using the modelformset_factory to build the form in the view using the DB model. The issue that I am having is that the is_valid() check before the save() is not working. When I submit the form with empty fields it still passes the is_valid() and attempts to write to the DB.

I would like the is_valid() check to fail when the fields are empty so that the user can be directed to the form again with an error message. I believe that there is a simple solution to this. Do you know what I am missing in my code?

Thanks.

Code:

models.py

class Response(models.Model):
    name = models.CharField(max_length=50,verbose_name='Your Name:')
    email = models.CharField(max_length=50,verbose_name='Email:')
    phone = models.CharField(max_length=50,verbose_name='Phone Number:')
    apt_size = models.CharField(max_length=25,
                                choices=APT_CHOICES,
                                verbose_name='Apt Size:')
    movein_at= models.DateField(verbose_name='Desired Move-In Date')
    community = models.CharField(max_length=50,
                                 choices=COMMUNITY_CHOICES,
                                 verbose_name='Community You Are Interested In:')
    referred_by = models.CharField(max_length=50,
                                   choices=REFERRED_CHOICES,
                                   verbose_name='Found Us Where?')
    referred_other = models.CharField(blank=True,max_length=50,verbose_name='If Other:')
    comments = models.TextField(verbose_name='Comments:')
    created_at = models.DateTimeField(auto_now_add=True)
    def __unicode__(self):
        return self.name

views.py

from summitpark.contact.models import * 
from django.shortcuts import render_to_response
from django.forms.models import modelformset_factory

def form(request):
    contact_form_set = modelformset_factory(Response,fields=('name','email','phone',
                                                            'apt_size','movein_at',
                                                            'community','referred_by',
                                                            'comments'),
                                                    exclude=('id'))
    if request.method == 'POST':
        formset = contact_form_set(request.POST)
        if formset.is_valid():
            formset.save()
            return render_to_response('contact/confirm.html')
        else: 
            return render_to_response('contact/form.html',{'formset':formset})
    else:
        formset = contact_form_set(queryset=Response.objects.none())
        return render_to_response('contact/form.html',{'formset':formset}

Solution:

class BaseContactFormSet(BaseModelFormSet):
def clean(self):
    if any(self.errors):
        return
    for form in self.forms:
        name = form['name'].data
        if not name:
            raise forms.ValidationError, "Please Complete the Required Fields

Your issue is that providing 0 items is a valid formset, there is no minimum validation. I'd provide a custom BaseModelFormset subclass that's clean() method just checked for a minimum of one obj.

Did you really want a formset ? I suspect if you have a contacts form with only one instance of the Response in then you want a ModelForm ...

class ResponseForm(forms.ModelForm):
    class Meta:
        model = Response
        fields=('name','email','phone',
               'apt_size','movein_at',
               'community','referred_by',
               'comments')

As for which fields are allowed to be blank and which aren't, make sure it does the right thing in the admin first, then the ModelForm will do exactly the right thing (that is how the admin makes its forms after all).

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM