我知道django会为简单的多对多表生成一个直通表。但是,如果要添加有关关系的信息,则需要一个“链接器”。或通过表格。 docs中的这个示例给出了一个示例:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self): # __unicode__ on Python 2
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __str__(self): # __unicode__ on Python 2
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
我在设计中有几个表格/模型,例如group
,这些表/模型大多只是choices
属性。我稍后会添加更多内容。
是否可以自定义Django的魔法生成什么样的直通表?如果是这样,这是明智的吗?
我正在谈论的是:
class CharacterSkillLink(models.Model):
character = models.ForeignKey('NWODCharacter', related_name='%(class)s_by_skill')
skill = models.ForeignKey('Skill', choices = SKILL_CHOICES)
value = models.IntegerRangeField(min_value=1, max_value=5)
speciality = models.CharField(max_length=200)
class CharacterAttributeLink(models.Model):
character = models.ForeignKey('NWODCharacter', related_name='%(class)s_by_skill')
attribute = models.ForeignKey('Attribute', choices = ATTRIBUTE_CHOICES)
value = model.IntegerRangeField(min_value=1, max_value=5
class CharacterArcanaLink(models.Model):
character = models.ForeignKey('Mage', related_name='%(class)s_by_skill')
arcana = models.ForeignKey('Arcana', choices = ARCANA_CHOICES)
value = model.IntegerRangeField(min_value=1, max_value=5
将来会更像这些。如果有某种方法可以使用django,就像使用through_field
属性定义要使用的直通表上的键一样,应该有额外的值添加到它(例如{{extra_field=value
属性。 1}})。
这可能/合理吗?
答案 0 :(得分:1)
IMO,将字段添加到"至" table是许多可能用途的绝佳模式。我不确定Django是否需要新的语法来处理这种情况,但是如果你认为你正在创建这些表的 lot 并混合/匹配不同的表,那么也许一些抽象的mixin会简化事情。例如:
class CharacterLink(models.Model):
character = models.ForeignKey('NWODCharacter')
class Meta:
abstract = True
class SkillLink(models.Model):
skill = models.ForeignKey('Skill', choices = SKILL_CHOICES)
class Meta:
abstract = True
class AttributeLink(models.Model):
attribute = models.ForeignKey('Attribute', choices = ATTRIBUTE_CHOICES)
class Meta:
abstract = True
class CharacterSkillLink(CharacterLink, SkillLink):
value = models.IntegerRangeField(min_value=1, max_value=5)
speciality = models.CharField(max_length=200)
class CharacterAttributeLink(CharacterLink, AttributeLink):
value = model.IntegerRangeField(min_value=1, max_value=5)