Django Unique Together (с внешними ключами)

У меня есть ситуация, когда я хочу использовать мета-опции unique_together для обеспечения соблюдения определенного правила, вот модель-посредник:

class UserProfileExtension(models.Model):
    extension = models.ForeignKey(Extension, unique=False)
    userprofile = models.ForeignKey(UserProfile, unique=False)
    user = models.ForeignKey(User, unique=False)  

    class Meta:
        unique_together = (("userprofile", "extension"),
                           ("user", "extension"),
                           # How can I enforce UserProfile's Client 
                           # and Extension to be unique? This obviously
                           # doesn't work, but is this idea possible without
                           # creating another FK in my intermediary model 
                           ("userprofile__client", "extension"))

и вот UserProfile:

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    client = models.ForeignKey(Client)

Спасибо.

57
задан 9 May 2019 в 11:30

3 ответа

Мои 2 цента, дополнение принятый ответ от @Wolph

, можно добавить проверку для него сами, хотя, просто перезаписывают validate_unique метод и добавляют эту проверку к нему.

Это - рабочий пример кода, который кто-то мог найти полезным.

from django.core.exceptions import ValidationError


class MyModel(models.Model):

    fk = models.ForeignKey(AnotherModel, on_delete=models.CASCADE)

    my_field = models.CharField(...)  # whatever

    def validate_unique(self, *args, **kwargs):
        super(MyModel, self).validate_unique(*args, **kwargs)

        if self.__class__.objects.\
                filter(fk=self.fk, my_field=self.my_field).\
                exists():
            raise ValidationError(
                message='MyModel with this (fk, my_field) already exists.',
                code='unique_together',
            )
5
ответ дан 1 November 2019 в 16:51

От django 2.2 + версии, предлагается использовать ограничение & Индекс как образцовый класс meta опция:

https://docs.djangoproject.com/en/2.2/ref/models/options/#django.db.models. Опции unique_together

https://docs.djangoproject.com/en/2.2/ref/models/options/#django.db.models. Options.constraints

2
ответ дан 1 November 2019 в 16:51

Необходимо звонить Модели full_clean () метод для вызова validate_unique для foreignKey. Можно переопределить, сохраняют () для вызова этого

class UserProfileExtension(models.Model):
    extension = models.ForeignKey(Extension, unique=False)
    userprofile = models.ForeignKey(UserProfile, unique=False)
    user = models.ForeignKey(User, unique=False)  


    def save(self, *args, **kwargs):
        self.full_clean()
        super().save(*args, **kwargs)

    class Meta:
        unique_together = (("userprofile", "extension"),
                       ("user", "extension"),
                       # How can I enforce UserProfile's Client 
                       # and Extension to be unique? This obviously
                       # doesn't work, but is this idea possible without
                       # creating another FK in my intermediary model 
                       ("userprofile__client", "extension"))
0
ответ дан 1 November 2019 в 16:51

Другие вопросы по тегам:

Похожие вопросы: