在 Django 中自动填充一组通用的多对多字段?
Autopopulate a set of generic many to many fields in Django?
我正在尝试将 this answer and this one 与一些 for 循环相结合。
在创建角色时,我想添加所有可能的值为 0 的技能,但我对如何遵循上述答案感到困惑。
我有这个混入:
class CrossCharacterMixin(models.Model):
cross_character_types = models.Q(app_label='mage', model='mage')
content_type = models.ForeignKey(ContentType, limit_choices_to=cross_character_types,
null=True, blank=True)
object_id = models.PositiveIntegerField(null=True)
content_object = GenericForeignKey('content_type', 'object_id')
class Meta:
abstract = True
(最终会扩展cross_character_types
)
而这个模型:
class CharacterSkillLink(Trait, CrossCharacterMixin):
PRIORITY_CHOICES = (
(1, 'Primary'), (2, 'Secondary'), (3, 'Tertiary')
)
skill = models.ForeignKey('SkillAbility')
priority = models.PositiveSmallIntegerField(
choices=PRIORITY_CHOICES, default=None)
speciality = models.CharField(max_length=200, null=True, blank=True)
def __str__(self):
spec_string = " (" + self.speciality + ")" if self.speciality else ""
return self.skill.skill.label + spec_string
我开始写的是这个,在 NWODCharacter 模型上:
def save(self, *args, **kwargs):
if not self.pk:
character_skills_through = CharacterSkillLink.content_object.model
CharacterSkillLink.objects.bulk_create([
[character_skills_through(skill=SkillAbility(
skill), content_object=self) for skill in SkillAbility.Skills]
])
super(NWODCharacter, self).save(*args, **kwargs)
这不起作用,因为我认为我没有传递正确的对象。
不过基于此answer:
from django.db import models
class Users(models.Model):
pass
class Sample(models.Model):
users = models.ManyToManyField(Users)
Users().save()
Users().save()
# Access the through model directly
ThroughModel = Sample.users.through
users = Users.objects.filter(pk__in=[1,2])
sample_object = Sample()
sample_object.save()
ThroughModel.objects.bulk_create([
ThroughModel(users_id=users[0].pk, sample_id=sample_object.pk),
ThroughModel(users_id=users[1].pk, sample_id=sample_object.pk)
])
在这种情况下,我的ThroughModel
是什么?是 CharacterSkillLink.content_object.model
吗?
如何在我的场景中执行此操作?如果这是微不足道的,我很抱歉,但我正在努力解决这个问题。
在我看来,在这种情况下,CharacterSkillLink
本身就是您的直通模型...它通常将内容类型连接到 SkillAbility
如果您仔细想想,如果您正在执行 bulk_create
,您传入的对象必须与您正在执行 bulk_create
的模型相同,这也是有道理的.
所以我想你想要这样的东西:
def save(self, *args, **kwargs):
initialise_skill_links = not self.pk
super(NWODCharacter, self).save(*args, **kwargs)
if initialise_skill_links:
CharacterSkillLink.objects.bulk_create([
CharacterSkillLink(
skill=SkillAbility.objects.get_or_create(skill=skill)[0],
content_object=self
)
for skill in SkillAbility.Skills
])
请注意,您的 bulk_create
中有太多对 []
。
此外,我认为您应该使用 SkillAbility.objects.get_or_create()
... 对于外键,您需要相关对象存在。如果它已经存在,只是做 SkillAbility()
不会从数据库中获取它,如果它不存在,也不会将它保存到数据库中。
我正在尝试将 this answer and this one 与一些 for 循环相结合。
在创建角色时,我想添加所有可能的值为 0 的技能,但我对如何遵循上述答案感到困惑。
我有这个混入:
class CrossCharacterMixin(models.Model):
cross_character_types = models.Q(app_label='mage', model='mage')
content_type = models.ForeignKey(ContentType, limit_choices_to=cross_character_types,
null=True, blank=True)
object_id = models.PositiveIntegerField(null=True)
content_object = GenericForeignKey('content_type', 'object_id')
class Meta:
abstract = True
(最终会扩展cross_character_types
)
而这个模型:
class CharacterSkillLink(Trait, CrossCharacterMixin):
PRIORITY_CHOICES = (
(1, 'Primary'), (2, 'Secondary'), (3, 'Tertiary')
)
skill = models.ForeignKey('SkillAbility')
priority = models.PositiveSmallIntegerField(
choices=PRIORITY_CHOICES, default=None)
speciality = models.CharField(max_length=200, null=True, blank=True)
def __str__(self):
spec_string = " (" + self.speciality + ")" if self.speciality else ""
return self.skill.skill.label + spec_string
我开始写的是这个,在 NWODCharacter 模型上:
def save(self, *args, **kwargs):
if not self.pk:
character_skills_through = CharacterSkillLink.content_object.model
CharacterSkillLink.objects.bulk_create([
[character_skills_through(skill=SkillAbility(
skill), content_object=self) for skill in SkillAbility.Skills]
])
super(NWODCharacter, self).save(*args, **kwargs)
这不起作用,因为我认为我没有传递正确的对象。
不过基于此answer:
from django.db import models class Users(models.Model): pass class Sample(models.Model): users = models.ManyToManyField(Users) Users().save() Users().save() # Access the through model directly ThroughModel = Sample.users.through users = Users.objects.filter(pk__in=[1,2]) sample_object = Sample() sample_object.save() ThroughModel.objects.bulk_create([ ThroughModel(users_id=users[0].pk, sample_id=sample_object.pk), ThroughModel(users_id=users[1].pk, sample_id=sample_object.pk) ])
在这种情况下,我的ThroughModel
是什么?是 CharacterSkillLink.content_object.model
吗?
如何在我的场景中执行此操作?如果这是微不足道的,我很抱歉,但我正在努力解决这个问题。
在我看来,在这种情况下,CharacterSkillLink
本身就是您的直通模型...它通常将内容类型连接到 SkillAbility
如果您仔细想想,如果您正在执行 bulk_create
,您传入的对象必须与您正在执行 bulk_create
的模型相同,这也是有道理的.
所以我想你想要这样的东西:
def save(self, *args, **kwargs):
initialise_skill_links = not self.pk
super(NWODCharacter, self).save(*args, **kwargs)
if initialise_skill_links:
CharacterSkillLink.objects.bulk_create([
CharacterSkillLink(
skill=SkillAbility.objects.get_or_create(skill=skill)[0],
content_object=self
)
for skill in SkillAbility.Skills
])
请注意,您的 bulk_create
中有太多对 []
。
此外,我认为您应该使用 SkillAbility.objects.get_or_create()
... 对于外键,您需要相关对象存在。如果它已经存在,只是做 SkillAbility()
不会从数据库中获取它,如果它不存在,也不会将它保存到数据库中。