GartenChoi
GartenChoi

Reputation: 21

How to define two Django fields unique in certain conditions

I want to make Django Model fields unique with two fields(values) in some conditions.

there's two fields: 'team', 'type'. And I want to make team manager unique

For Example:

team=1, type='manager'
team=1, type='manager'

-> Not available

team=1, type='manager'
team=1, type='member'
team=1, type='member'
team=2, type='manager'

-> Available

I think unique_together('team', 'type') won't work properly with this situation.

How can I make this with Django Model?

Here's my model below:

class myModel(models.Model):
    team = models.ForeignKey('Team', on_delete=models.CASCADE)
    type = models.CharField(max_length=10, default='member')
    class Meta:
        db_table = 'my_models'

Upvotes: 1

Views: 1319

Answers (2)

Nic
Nic

Reputation: 328

Given that there is a deprecation warning in the documentation (based on 3.2 docs) for unique_together, I think it's worth showing that this can be done using UniqueConstraint. I believe that the key missing ingredient from the previous answer is the use of UniqueConstraint.condition, like so:

from django.db import models
from django.db.models import Q, UniqueConstraint

class myModel(models.Model):
    team = models.ForeignKey('Team', on_delete=models.CASCADE)
    type = models.CharField(max_length=10, default='member')
    class Meta:
        db_table = 'my_models'
        constraints = [
            UniqueConstraint(
                fields=['team', 'type'],
                name='unique_team',
                condition=Q(type='manager')
            )
        ]

Upvotes: 2

Devang Hingu
Devang Hingu

Reputation: 628

I think, You need to use UniqueConstraint for your application which work perfect in kind of situation.

class myModel(models.Model):
    team = models.ForeignKey('Team', on_delete=models.CASCADE)
    type = models.CharField(max_length=10, default='member')
    class Meta:
        db_table = 'my_models'
        constraints = [
             models.UniqueConstraint(fields=['team', 'type'], name='unique_team')
        ]

you can also refer this link for more understanding. and let me know if following solution will work.

Upvotes: 1

Related Questions