Models.clean() how to raise ValidationError WITH error_code and show field_based errors in the Form-Template?

950 views
Skip to first unread message

ThomasTheDjangoFan

unread,
Jul 30, 2015, 6:10:39 AM7/30/15
to Django users
Hi guys,

I got a working model.clean() method that actually does a great job showing the errors in the assigned html-form. The view actually marks single invalid fields red, which I find really important.

BUT:
Now I want to write a test for that model and would love to test for error_codes.

Does anyone know how to raise an error_code-exception within the model and keep the view rendering the invalid-fields correctly?

Ok... I think it's easier to understand with some code:


class MyNotebookModel(models.Model):
    note
= models.TextField()
    name
= models.CharField()

   
def clean(self):
        errors
= defaultdict(list)
       
# errors = {}  # does NOT work with view

       
# Validate self.note
       
if 'P.S. I love django!' not in self.note:
            message
= 'BadAss: Give some credits to Django!'
            errors
['note'].append(message)
           
# errors.append(ValidationError(_(message), code=1))  # does NOT work in view

       
# Validate self.name
       
if 'Steven' not in self.note:
            message
= 'BadAss: I only allow names with Steven'
            errors
['note'].append(message)
           
# errors.append(ValidationError(_(message), code=2))  # does NOT work in view

       
if len(errors):
           
raise ValidationError(errors)


class TestMyNotebookCreateView(CreateView):
   
# in my View I want to show errors by field and mark the error-fields RED
   
# it works with the above approach, but NOT with error_codes



class TestMyNotebookModelTest(unittest):
   
def test_clean(self):
       
# I'd love to be able to do a test like this one
        # and valide the error code!

        # Lets get an error-message
       
with self.assertRaises(ValidationError) as test:
            model
= MyNotebookModel()
            model
.note = 'Now this is a valid one. P.S. I love django!'
            model
.name = 'Britney is gonna fail - Hit me Baby One More Time!'
            model
.clean()
            model
.save()
       
# validate that the error messages has the right code
        the_exception
= test.exception
       
self.assertEqual(the_exception.error_code, 2)


Any ideas how to make this work?
What is best practise?

jordi collell

unread,
Aug 2, 2015, 6:34:18 PM8/2/15
to Django users
An easy way is to test that the rendered form has the error message raised suring rhe validation.

ThomasTheDjangoFan

unread,
Aug 3, 2015, 4:10:51 AM8/3/15
to Django users
Hi Jordi,

thanks a lot for your response!

Yeah definetly, BUT this error message could change during development and I guess that is the reason why the django-docs recon you to set error_codes. This why you wouldn't have to touch the tests when changing the error-message but keeping the error-code the same.

Any other ideas?

Does anyone know how to raise an error_code-exception within the model and keep the view rendering the invalid-fields correctly?


Peter of the Norse

unread,
Aug 29, 2015, 6:39:46 PM8/29/15
to django...@googlegroups.com
You are raising a dict style ValidationError.  To get the actual fields you need to use the_exception.error_dict[’note’].error_list[0].code.  

On Jul 30, 2015, at 4:10 AM, ThomasTheDjangoFan <stefan.eich...@googlemail.com> wrote:

class TestMyNotebookModelTest(unittest):
    
def test_clean(self):
        
# I'd love to be able to do a test like this one
        # and valide the error code!

        # Lets get an error-message
        
with self.assertRaises(ValidationError) as test:
            model 
= MyNotebookModel()
            model
.note = 'Now this is a valid one. P.S. I love django!'
            model
.name = 'Britney is gonna fail - Hit me Baby One More Time!'
            model
.clean()
            model
.save()
        
# validate that the error messages has the right code
        the_exception 
= test.exception
        
self.assertEqual(the_exception.error_code, 2)

Peter of the Norse



Reply all
Reply to author
Forward
0 new messages