Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specific way of requiring one of two fields in django model definition

Tags:

python

django

I have model MyModel with fields field1 and field2. I want to require either one of these two fields. How can I do this?

class MyModel(models.Model):
    field1 = models.TextField(?)
    field2 = models.TextField(?)

I am looking for a specific, best-practice way that I have seen but forgotten, not the overriding clean function method. I do remember the method overriding some function, but I don't think it was clean.

Thanks in advance

like image 541
Michael Avatar asked Sep 18 '17 18:09

Michael


People also ask

What is an instance of a field class in Django?

Each field in the model should be an instance of the appropriate Field class. Django uses field class types to determine a few things: The column type, which tells the database what kind of data to store (e.g. INTEGER, VARCHAR, TEXT).

What are model data types and fields in Django?

Django model data types and fields list. The most important part of a model and the only required part of a model is the list of database fields it defines. Fields are specified by class attributes. Be careful not to choose field names that conflict with the models API like clean, save, or delete.

What are the arguments available in Django field types?

The following arguments are available in Django field types: Sometimes business logic requires relationships among attributes of different model classes. There are three field relationships in Django models: ManyToManyField (). ForeignKey is like a many-to-one relationship. It requires two positional arguments namely Classname and on_delete.

What is the difference between models and Orm in Django?

Django uses ORM (Object Relational Mapping) that allows us to perform database operations without writing SQL queries but with simple python objects. models is a module that packs the definitions for Model classes, different models fields, and field relationships.


Video Answer


2 Answers

This is an old question, but since this was the first hit for me when I searched for "django model field require one of two", I should point out that while overriding clean() may have been a good practise 3 years ago, Django's support for database constraint definitions in the Meta class is a much better choice for this these days. This tutorial put me on the right path, but here's a code sample from our model:

class MyModel:

    thing1 = models.PositiveIntegerField(null=True)
    thing2 = models.PositiveIntegerField(null=True)

    class Meta:
        constraints = [
            models.CheckConstraint(
                name="%(app_label)s_%(class)s_thing1_or_thing2",
                check=(
                    models.Q(thing1__isnull=True, thing2__isnull=False)
                    | models.Q(thing1__isnull=False, thing2__isnull=True)
                ),
            )
        ]
like image 148
Daniel Quinn Avatar answered Oct 07 '22 20:10

Daniel Quinn


As commented use clean

class MyModel(models.Model):
    field1 = models.TextField(blank=True)
    field2 = models.TextField(blank=True)

    def clean(self):
        cleaned_data = super().clean()
        if not cleaned_data.get('field1') and not cleaned_data.get('field2'):  # This will check for None or Empty
            raise ValidationError({'field1': 'Even one of field1 or field2 should have a value.'})
like image 12
Serjik Avatar answered Oct 07 '22 21:10

Serjik