3

Edit: I am using PostgreSQL

I have a model that has 4 phone number fields, and I run a ValidationError at the Model level using clean:

class Person(models.Model):

    personal_phone_mobile = PhoneNumberField()
    personal_phone_direct = PhoneNumberField()
    company_phone_mobile = PhoneNumberField()
    company_phone_direct = PhoneNumberField()

   def clean(self):
        """Ensure that at least one phone number for personal and company 
           contact phone is provided (either mobile or direct)."""

        error_dict = {}
        if self.personal_id_type == 0 and self.personal_id:
            error_dict['personal_id_type'] = ValidationError(
                "ID type can not be 'None' if you have set a value."
            )
        if self.personal_phone_mobile is None and self.personal_phone_direct is None:
            error_dict['personal_phone_direct'] = ValidationError(
                'Please enter at least one personal phone number'
            )
            error_dict['personal_phone_mobile'] = ValidationError(
                'Please enter at least one personal phone number'
            )
        if self.company_phone_mobile is None and self.company_phone_direct is None:
            error_dict['company_phone_direct'] = ValidationError(
                'Please enter at least one company phone number'
            )
            error_dict['company_phone_mobile'] = ValidationError(
                'Please enter at least one company phone number'
            )
        if error_dict:
            raise ValidationError(error_dict)

This works fine as expected.

In Django 2.2, model Contraints were introduced which create constraints at the database level.

Is it best practice to:

  1. Replace model ValidationError with Constraint
  2. Use only ValidationErrors (I am not sure the above logic is possible with a Constraint?)
  3. Keep both?

If the answer is either 1 or 3, how would I create the same logic of my ValidationError in a Constraint?

alias51
  • 8,178
  • 22
  • 94
  • 166
  • 2
    `Constraint`s run on the database (and *some* databases like some versions of MySQL even completely ingore the constraints). It will furthermore not give (much) meaningful errors. Normally the form will say that it is valid, even if it is not (there are some exceptions with `UniqueConstraint`s). It is good to enfroce constraints at the database level as well. But likely better to give meaningful error messages. – Willem Van Onsem Jan 04 '20 at 16:43
  • 1
    @WillemVanOnsem Thank you. So assuming the best option is to keep the `ValidationError` but also use `Constraint`, is it possible to use a `Constraint` conditionally in the way shown? If so, do you know what the syntax would look like? Documentation in Django on `Q` is unfortunately not verbose. – alias51 Jan 04 '20 at 16:45

0 Answers0