Короче говоря : я думаю, что ограничение уникальности должно быть наложено на атрибут role
модели Role
, чтобы предотвратить создание нескольких Role
с одним и тем же атрибутом role
.
Моделирование этого отношения многие ко многим
Мне кажется, вы хотите использовать отношение многие ко многим здесь, поскольку это означает, что Person
может иметь много Role
с, а Role
может быть связано с многими Person
с.
Вам, вероятно, следует сделать поле role
(хотя, возможно, name
здесь лучше) уникально , так что один не может создать две роли с одинаковым именем:
class Role(models.Model):
role = models.CharField(max_length=200<b>, unique=True</b>)
<b>persons = models.ManyToManyField(Person, related_name='roles'</b>)
def __str__(self):
return self.role
class Meta:
ordering = ('role',)
Мы можем создать два Person
с именами обоих художников:
role_artist, __ = Role.objects.get_or_create(role='artist')
adam = Person.objects.create(firstName='Adam')
david = Person.objects.create(firstName='David')
adam.roles.add(role_artist)
david.roles.add(role_artist)
Name
как - модель
Модель Name
, которую вы определяете, похоже, работает как модель Through
: она добавляет дополнительные данные в отношение.Например, у человека может быть два Name
с: один как певец и один как кинозвезда.Обычно это вариант использования through
модели [Django-doc] , где можно кодировать дополнительные данные в отношении, хотя, возможно, было бы лучше назвать это Alias
(или, по крайней мере, более описательное имя).
Мы можем перемоделировать это как:
class Role(models.Model):
role = models.CharField(max_length=200, unique=True)
persons = models.ManyToManyField(Person<b>, through='Alias'</b>, related_name='roles')
def __str__(self):
return self.role
class Meta:
ordering = ('role',)
class <b>Alias</b>(models.Model):
name = models.CharField(max_length=200)
role = models.ForeignKey(Role, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
Затем мы можем сделать два Person
s adam
и david
, которые оба являются художникамии каждый с именем исполнителя:
role_artist, __ = Role.objects.get_or_create(role='artist')
adam = Person.objects.create(firstName='Adam')
david = Person.objects.create(firstName='David')
Alias.objects.create(name='Adam the magician', role=role_artist, person=adam)
Alias.objects.create(name='David the lion tamer', role=role_artist, person=david)
даже возможно, что Person
имеет несколько Alias
ses для одной и той же роли.
Заключительные замечания
Примечание : в соответствии с PEP 8 соглашение об именах состоит в том, что атрибуты являются строчными, а слова разделяются подчеркиванием.То есть это должно быть first_name
вместо firstName
.