Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Fix for Ticket #11160 #1094

Merged
merged 2 commits into from 11 months ago

2 participants

Senko Rašić Andrew Godwin
added some commits May 18, 2013
Senko Rašić Fixed #11160 - Ensure full_clean is called from non_form_errors
Updated FormSet.non_form_errors() to ensure full_clean() has
been called before returning the errors.
493aca4
Senko Rašić Added myself to AUTHORS b11b036
Andrew Godwin andrewgodwin merged commit 04e0fc0 into from May 19, 2013
Andrew Godwin andrewgodwin closed this May 19, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 2 unique commits by 1 author.

May 18, 2013
Senko Rašić Fixed #11160 - Ensure full_clean is called from non_form_errors
Updated FormSet.non_form_errors() to ensure full_clean() has
been called before returning the errors.
493aca4
Senko Rašić Added myself to AUTHORS b11b036
This page is out of date. Refresh to see the latest.
1  AUTHORS
@@ -468,6 +468,7 @@ answer newbie questions, and generally made Django that much better:
468 468
     Luciano Ramalho
469 469
     Amit Ramon <amit.ramon@gmail.com>
470 470
     Philippe Raoult <philippe.raoult@n2nsoft.com>
  471
+    Senko Rašić <senko.rasic@dobarkod.hr>
471 472
     Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
472 473
     Brian Ray <http://brianray.chipy.org/>
473 474
     Lee Reilly <lee@leereilly.net>
11  django/forms/formsets.py
@@ -250,9 +250,9 @@ def non_form_errors(self):
250 250
         form -- i.e., from formset.clean(). Returns an empty ErrorList if there
251 251
         are none.
252 252
         """
253  
-        if self._non_form_errors is not None:
254  
-            return self._non_form_errors
255  
-        return self.error_class()
  253
+        if self._non_form_errors is None:
  254
+            self.full_clean()
  255
+        return self._non_form_errors
256 256
 
257 257
     @property
258 258
     def errors(self):
@@ -291,9 +291,12 @@ def is_valid(self):
291 291
 
292 292
     def full_clean(self):
293 293
         """
294  
-        Cleans all of self.data and populates self._errors.
  294
+        Cleans all of self.data and populates self._errors and
  295
+        self._non_form_errors.
295 296
         """
296 297
         self._errors = []
  298
+        self._non_form_errors = self.error_class()
  299
+
297 300
         if not self.is_bound: # Stop further processing.
298 301
             return
299 302
         for i in range(0, self.total_form_count()):
14  tests/forms_tests/tests/test_formsets.py
@@ -972,6 +972,20 @@ def test_increase_hard_limit(self):
972 972
         finally:
973 973
             formsets.DEFAULT_MAX_NUM = _old_DEFAULT_MAX_NUM
974 974
 
  975
+    def test_non_form_errors_run_full_clean(self):
  976
+        # Regression test for #11160
  977
+        # If non_form_errors() is called without calling is_valid() first,
  978
+        # it should ensure that full_clean() is called.
  979
+        class BaseCustomFormSet(BaseFormSet):
  980
+            def clean(self):
  981
+                raise ValidationError("This is a non-form error")
  982
+
  983
+        ChoiceFormSet = formset_factory(Choice, formset=BaseCustomFormSet)
  984
+        formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
  985
+        self.assertTrue(isinstance(formset.non_form_errors(), ErrorList))
  986
+        self.assertEqual(list(formset.non_form_errors()),
  987
+            ['This is a non-form error'])
  988
+
975 989
 
976 990
 data = {
977 991
     'choices-TOTAL_FORMS': '1', # the number of forms rendered
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.