Django:带有中间模型错误的ManyToManyField
Django: ManyToManyField with intermediary model error
Django 不为我们管理数据库,因此我创建了 table RulesetRuleMap
来处理 Ruleset
和 Rule
之间的 ManyToMany
关系:
每个 Ruleset
可以由多个 Rules
组成,每个 Rule
可以在多个 Rulesets
.
中使用
型号
class Rule(models.Model):
id = models.BigAutoField(primary_key=True)
percentage_of_total = models.FloatField(blank=False, null=False)
_rule_parameter = models.ForeignKey('RuleParameter', models.DO_NOTHING, blank=False, null=False)
class Meta:
managed = False
db_table = '_rule'
class Ruleset(models.Model):
id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=300, blank=False, null=False)
description = models.CharField(max_length=300, blank=False, null=False)
rules = models.ManyToManyField('Rule', through="RulesetRuleMap")
class Meta:
managed = False
db_table = '_ruleset'
class RulesetRuleMap(models.Model):
id = models.BigAutoField(primary_key=True)
_rule = models.ForeignKey('Rule', models.CASCADE)
_ruleset = models.ForeignKey('Ruleset', models.CASCADE)
class Meta:
managed = False
db_table = '_ruleset_rule_map'
序列化器
class RulesetRuleMapSerializer(serializers.ModelSerializer):
class Meta:
model = db_models.RulesetRuleMap
fields = '__all__'
class RuleSerializer(serializers.ModelSerializer):
class Meta:
model = db_models.Rule
fields = '__all__'
class RulesetSerializer(serializers.ModelSerializer):
rules = RuleSerializer(many=True)
class Meta:
model = db_models.Ruleset
fields = '__all__'
def create(self, validated_data):
rules_data = validated_data.pop('rules')
ruleset = db_models.Ruleset.objects.create(**validated_data)
rules_storage =[]
for rule_data in rules_data:
rule, created = db_models.Rule.objects.get_or_create(**rule_data)
rules_storage.append(rule)
ruleset.rules.add(*rules_storage, through_defaults={})
return ruleset
在主页上,用户可以 add/modify Ruleset
和 add/modify 关联 Rules
。提交后,我们收到这样的有效负载:
{
"id": None,
"name": "Split_50.0_Param1_50.0_Param2",
"description": "test",
"rules": [
{
"id": None,
"percentage_of_total": "50",
"tc_rule_parameter": "3"
},
{
"id": None,
"percentage_of_total": "50",
"tc_rule_parameter": "2"
}
]
}
如Djange REST Framework I defined a custom create()
for the nested RulesetSerializer
to handle the creation of multiple objects. According to Django中所述,应该可以
use add(), create(), or set() to create relationships, as long as you specify through_defaults for any required fields.
执行ruleset.rules.add(*rules_storage, through_defaults={})
时出现错误
{TypeError}add() got an unexpected keyword argument 'through_defaults'
执行ruleset.rules.add(*rules_storage)
时出现错误
{AttributeError}Cannot use add() on a ManyToManyField which specifies an intermediary model.Use database_models.TcRulesetRuleMap's Manager instead.
我的模型 and/or 序列化程序设置有误还是 django 中有错误?
正如那里所说:
Cannot use add() on a ManyToManyField which specifies an intermediary model.
您已经通过模型指定了自己的对象,RulesetRuleMap
,因此您需要自己创建对象,因为 django 不支持 add()
这种情况。
如果您想使用 add()
、create()
或 set()
,那么根据下面列出的文档,您需要为任何需要的内容传递 kwarg through_defaults
领域。您没有任何额外的必填字段,因此需要对您的特定模型集进行调试。
这种与直通模型的关系的 DRF 文档是 here
django 文档中有一个很好的示例,用于使用直通模型设置对象 here
示例中有3个模型,Person
、Group
和Membership
。 Group
通过 Membership
到 Person
的 M2M。
>>> ringo = Person.objects.create(name="Ringo Starr")
>>> paul = Person.objects.create(name="Paul McCartney")
>>> beatles = Group.objects.create(name="The Beatles")
>>> m1 = Membership(person=ringo, group=beatles,
... date_joined=date(1962, 8, 16),
... invite_reason="Needed a new drummer.")
>>> m1.save()
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>]>
>>> ringo.group_set.all()
<QuerySet [<Group: The Beatles>]>
>>> m2 = Membership.objects.create(person=paul, group=beatles,
... date_joined=date(1960, 8, 1),
... invite_reason="Wanted to form a band.")
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>]>
我误读了 django 文档。我在 django 2.1 上,through 字段只在 2.2 中引入。
Django 不为我们管理数据库,因此我创建了 table RulesetRuleMap
来处理 Ruleset
和 Rule
之间的 ManyToMany
关系:
每个 Ruleset
可以由多个 Rules
组成,每个 Rule
可以在多个 Rulesets
.
型号
class Rule(models.Model):
id = models.BigAutoField(primary_key=True)
percentage_of_total = models.FloatField(blank=False, null=False)
_rule_parameter = models.ForeignKey('RuleParameter', models.DO_NOTHING, blank=False, null=False)
class Meta:
managed = False
db_table = '_rule'
class Ruleset(models.Model):
id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=300, blank=False, null=False)
description = models.CharField(max_length=300, blank=False, null=False)
rules = models.ManyToManyField('Rule', through="RulesetRuleMap")
class Meta:
managed = False
db_table = '_ruleset'
class RulesetRuleMap(models.Model):
id = models.BigAutoField(primary_key=True)
_rule = models.ForeignKey('Rule', models.CASCADE)
_ruleset = models.ForeignKey('Ruleset', models.CASCADE)
class Meta:
managed = False
db_table = '_ruleset_rule_map'
序列化器
class RulesetRuleMapSerializer(serializers.ModelSerializer):
class Meta:
model = db_models.RulesetRuleMap
fields = '__all__'
class RuleSerializer(serializers.ModelSerializer):
class Meta:
model = db_models.Rule
fields = '__all__'
class RulesetSerializer(serializers.ModelSerializer):
rules = RuleSerializer(many=True)
class Meta:
model = db_models.Ruleset
fields = '__all__'
def create(self, validated_data):
rules_data = validated_data.pop('rules')
ruleset = db_models.Ruleset.objects.create(**validated_data)
rules_storage =[]
for rule_data in rules_data:
rule, created = db_models.Rule.objects.get_or_create(**rule_data)
rules_storage.append(rule)
ruleset.rules.add(*rules_storage, through_defaults={})
return ruleset
在主页上,用户可以 add/modify Ruleset
和 add/modify 关联 Rules
。提交后,我们收到这样的有效负载:
{
"id": None,
"name": "Split_50.0_Param1_50.0_Param2",
"description": "test",
"rules": [
{
"id": None,
"percentage_of_total": "50",
"tc_rule_parameter": "3"
},
{
"id": None,
"percentage_of_total": "50",
"tc_rule_parameter": "2"
}
]
}
如Djange REST Framework I defined a custom create()
for the nested RulesetSerializer
to handle the creation of multiple objects. According to Django中所述,应该可以
use add(), create(), or set() to create relationships, as long as you specify through_defaults for any required fields.
执行ruleset.rules.add(*rules_storage, through_defaults={})
时出现错误
{TypeError}add() got an unexpected keyword argument 'through_defaults'
执行ruleset.rules.add(*rules_storage)
时出现错误
{AttributeError}Cannot use add() on a ManyToManyField which specifies an intermediary model.Use database_models.TcRulesetRuleMap's Manager instead.
我的模型 and/or 序列化程序设置有误还是 django 中有错误?
正如那里所说:
Cannot use add() on a ManyToManyField which specifies an intermediary model.
您已经通过模型指定了自己的对象,RulesetRuleMap
,因此您需要自己创建对象,因为 django 不支持 add()
这种情况。
如果您想使用 add()
、create()
或 set()
,那么根据下面列出的文档,您需要为任何需要的内容传递 kwarg through_defaults
领域。您没有任何额外的必填字段,因此需要对您的特定模型集进行调试。
这种与直通模型的关系的 DRF 文档是 here
django 文档中有一个很好的示例,用于使用直通模型设置对象 here
示例中有3个模型,Person
、Group
和Membership
。 Group
通过 Membership
到 Person
的 M2M。
>>> ringo = Person.objects.create(name="Ringo Starr")
>>> paul = Person.objects.create(name="Paul McCartney")
>>> beatles = Group.objects.create(name="The Beatles")
>>> m1 = Membership(person=ringo, group=beatles,
... date_joined=date(1962, 8, 16),
... invite_reason="Needed a new drummer.")
>>> m1.save()
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>]>
>>> ringo.group_set.all()
<QuerySet [<Group: The Beatles>]>
>>> m2 = Membership.objects.create(person=paul, group=beatles,
... date_joined=date(1960, 8, 1),
... invite_reason="Wanted to form a band.")
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>]>
我误读了 django 文档。我在 django 2.1 上,through 字段只在 2.2 中引入。