Tuesday, June 5, 2012

raise ValidationError not working

I have the following models:

class Project(models.Model):
    title
= models.CharField(max_length="100")

    pub_date
= models.DateField(auto_now_add=True, editable=False)

    budget
= models.IntegerField()

class Milestone(models.Model):

    title
= models.CharField(max_length="50")

    budget_percentage
= models.IntegerField(max_length=2)

    project
= models.ForeignKey(Project)

In the creation form for a Project, i've included an inline formset for milestones.

I want to validate that when a Project is subbmitted, at least 4 milestones are created, also that the budget_percentage of all milestones sums up to 100

This is my form:

class BaseMilestoneProjectFormSet(BaseFormSet):
   
def clean(self):

       
if any(self.errors):
           
# Don't bother validating the forms unless each form is valid on its own
           
return

       
if len(self.forms) < REQUIRED_MILESTONES:
           
raise forms.ValidationError("At least %s milestones need to be created" % REQUIRED_MILESTONES)

       
# Set initial control variables
       
# Total percentage of budget to control
        total_percentage
= 0
       
# Date to control that milestones are linear, i.e. that second milestone isn't delivered before first
        current_control_date
= date.min

       
for i, form in zip(range(len(self.forms)), self.forms):

           
if i == 0 and form.budget_percentage > MAX_BUDGET_FIRST_MILESTONE:
               
raise forms.ValidationError("First milestone budget must not exceed %s percentage" % MAX_BUDGET_FIRST_MILESTONE)
           
elif form.budget_percentage > MAX_BUDGET_MILESTONE:
               
raise forms.ValidationError("Milestone's budget must not exceed %s percentage" % MAX_BUDGET_MILESTONE)

           
if form.estimated_delivery_date < current_control_date:
               
raise forms.ValidationError("Milestones must be linear, check your delivery dates")

           
# Set control variables for next iteration    
            current_control_date
= form.estimated_delivery_date                
            total_percentage
+= form.budget_percentage

       
if total_percentage != 100:
           
raise forms.ValidationError("All milestones budget percentage should sum up to 100%")

Views.py:

class DelayedModelFormMixin(ModelFormMixin):
   
def form_valid(self, form):
       
self.object = form.save(commit=False)
       
self.prepare_object_for_save(self.object)
       
self.object.save()
       
if hasattr(self.object, "save_m2m"):
           
self.object.save_m2m()
       
return super(ModelFormMixin, self).form_valid(form)

   
def prepare_object_for_save(self, obj):
       
pass

class ProjectNew(CreateView, DelayedModelFormMixin):
    model
= Project
    success_url
= '/projects/project/%(slug)s'
    form_class
= ProjectForm

   
@method_decorator(login_required)
   
def dispatch(self, request, *args, **kwargs):
       
return super(ProjectNew, self).dispatch(request, *args, **kwargs)

   
def prepare_object_for_save(self, obj):
        obj
.owner = self.request.user
       
# Code for stacked milestones and rewards
        context
= self.get_context_data()
        milestone_form
= context['milestone_formset']
        reward_form
= context['reward_formset']
       
if milestone_form.is_valid() and reward_form.is_valid():
           
self.object = form.save()
            milestone_form
.instance = self.object
            milestone_form
.save()
            reward_form
.instance = self.object
            reward_form
.save()
           
return HttpResponseRedirect(success_url)

   
def form_invalid(self, form):
       
return self.render_to_response(self.get_context_data(form=form))

   
def get_context_data(self, **kwargs):
        context
= super(ProjectNew, self).get_context_data(**kwargs)
       
if self.request.POST:
            context
['milestone_formset'] = MilestoneFormSet(self.request.POST)
            context
['reward_formset'] = RewardFormSet(self.request.POST)
       
else:
            context
['milestone_formset'] = MilestoneFormSet()
            context
['reward_formset'] = RewardFormSet()
       
return context

When I submit the form with 3 empty milestones forms it doesn't do nothing about the first forms.ValidationError(...). I mean, it is not valid, but django is redirecting to the success page, instead of showing the corresponding errors. In the first if 

if len(self.forms) < REQUIRED_MILESTONES:

I've tested that len(self.forms) equals 3 and REQUIRED_MILESTONES is 4. Also with a generic "raise Exception("test message") i've tested that the if evaluates to True, and it is executing inside code, but for some reason the ValidationError isn't raising as expected (or at least as I expected)

It's an error in my code or a misunderstood concept of ValidationError?

Any help would be greatly appreciated, thanks in advance.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/eB2i_CIaS08J.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home


Real Estate