H C*_*H C 0 django django-models django-queryset
我有一个人物模型。
class Person(models.Model):
name_first = models.CharField(max_length=100)
name_middle = models.CharField(max_length=100, null=True, blank=True)
name_last = models.CharField(max_length=100)
date_birth = models.DateField(null=True, blank=True)
date_death = models.DateField(null=True, blank=True)
Run Code Online (Sandbox Code Playgroud)
我正在尝试将其扩展到音乐界的不同角色:作曲家,表演者和赞助人。
一个人可以是一个,两个或所有三个角色。如果某人是表演者,我还需要为该人分配一种或多种乐器。在实例化时,您可能不知道某人是否是表演者。否则他们的角色会随着时间而改变。
我希望能够搜索并显示一个人(如果他是三个人)既是作曲家,钢琴家又是赞助人。例如:贝多芬是指挥,作曲家和钢琴家。
我对实现的最初想法是继承Person类。
class Composer(Person):
pass
class Performer(Person):
instrument = models.ManyToManyField(Instrument, verbose_name=_('instrument'), blank=True,)
class Patron(Person):
pass
class Instrument(models.Model):
name = models.CharField(max_length=100, null=True, blank=True)
Run Code Online (Sandbox Code Playgroud)
问题1:我应该改用某种抽象模型吗?如果是这样,我将如何处理?
问题2:我如何寻找一个人,并知道他们是否是作曲家,赞助人和/或表演者,以及他们是哪种表演者。
谢谢。
我的方法是:定义一个基Person
类,并使其他模型对该模型具有外键。
首先,创建您的Person
课程。
class Person(models.Model):
name_first = models.CharField(max_length=100)
name_middle = models.CharField(max_length=100, null=True, blank=True)
name_last = models.CharField(max_length=100)
date_birth = models.DateField(null=True, blank=True)
date_death = models.DateField(null=True, blank=True)
@property
def is_performer(self):
return hasattr(self, 'performer_role')
@property
def is_patron(self):
return hasattr(self, 'patron_role')
@property
def is_composer(self):
return hasattr(self, 'composer_role')
@property
def roles(self):
roles = []
if self.is_performer:
roles.append('performer')
if self.is_patron:
roles.append('patron')
if self.is_composer:
roles.append('composer')
return roles
Run Code Online (Sandbox Code Playgroud)
其次,创建您的特定模型并为该人员设置外键。
class ComposerRole(models.Model):
person = models.OneToOneField(Person, on_delete=models.CASCADE, related_name='composer_role')
# other fields as necessary
class PerformerRole(models.Model):
person = models.OneToOneField(Person, on_delete=models.CASCADE, related_name='performer_role')
instrument = models.CharField(max_length=100, blank=True)
performer_type = models.CharField(max_length=100, blank=True) //conductor, performer
# other fields as necessary
class PatronRole(models.Model):
person = models.OneToOneField(Person, on_delete=models.CASCADE, related_name='patron_roll')
# other fields as necessary
Run Code Online (Sandbox Code Playgroud)
要实例化具有正确角色的新人,您可以像这样添加他们:
p = Person.objects.create(...)
PerformerRole.objects.create(person=p, instrument='...')
Run Code Online (Sandbox Code Playgroud)
要检查某人是否有角色,只需执行person_instance.is_performer
。要获取该角色的数据,请执行person_instance.performer_role.instrument
。
这种方法的另一个好处是,它允许您查询作曲家,顾客和表演者,例如ComposerRole.objects.all()
或ComposerRole.objects.filter(person__last_name='Beethoven')
。
希望能有所帮助。
编辑:添加roles
到Person
。这样,您就可以通过一个人获得所有角色person_instance.roles
。