#python #django #django-models
#python #django #django-модели
Вопрос:
Есть ли способ сделать поля модели уникальными для других моделей, ссылающихся на тот же внешний ключ?
В моем случае я пытаюсь сделать так, чтобы names
из Attribute
моделей с одинаковым Obj
значением были уникальными. Пример: если существует CharAttribute
с name='Types'
и obj=1
, не может быть другого CharAttribute
с name='Types'
и obj=1
, ни IntAttribute
с name='Types'
и obj=1
class Obj (models.Model):
name = models.CharField(max_length=40)
class CharAttribute (models.Model):
name = models.CharField(max_length=40)
obj = models.ForeignKey(Obj, on_delete=models.CASCADE)
class IntAttribute (models.Model):
name = models.CharField(max_length=40)
obj = models.ForeignKey(Obj, on_delete=models.CASCADE)
Моя текущая идея решения была бы примерно такой:
def clean_fields(self, exclude=None):
super().clean_fields(exclude=exclude)
for other_name in IntAttribute.objects.filter(obj=self.obj):
if self.name == other_name:
raise ValidationError(
('Attributes of the same object may not have the same name, %(name) s already exists for '
'%(object) s' % {'name': self.name, 'object': self.obj.name})
)
for other_name in CharAttribute.objects.filter(obj=self.obj):
if self.name == other_name:
raise ValidationError(
('Attributes of the same object may not have the same name, %(name) s already exists for '
'%(object) s' % {'name': self.name, "object": self.obj.name})
)
Но создание другого цикла for для каждого возможного будущего, созданного Attribute
, кажется повторяющимся, и должен быть лучший способ выполнения этой задачи.
Заранее благодарю вас за отзыв.
Ответ №1:
Вы можете использовать unique_together, чтобы убедиться, что ни одна комбинация полей не повторяется в модели:
class CharAttribute (models.Model):
name = models.CharField(max_length=40)
obj = models.ForeignKey(Obj, on_delete=models.CASCADE)
class Meta:
unique_together = ('name', 'obj')
Между моделями вам придется выполнять проверку вручную:
class CharAttribute (models.Model):
name = models.CharField(max_length=40)
obj = models.ForeignKey(Obj, on_delete=models.CASCADE)
class Meta:
unique_together = ('name', 'obj')
def clean(self):
if IntAttribute.objects.filter(name=self.name, obj=self.obj).exists():
raise ValidationError('...')
Тот же метод применяется для другой модели.
Комментарии:
1. Я чувствую себя идиотом с циклами for, спасибо, ха-ха