首页 > 解决方案 > Django:ManyToManyField 中间模型错误

问题描述

Django 并没有为我们管理我们的数据库,因此我创建了一个表RulesetRuleMap来处理和之间的关系ManyToMany:每个可以由多个组成,每个可以在多个.RulesetRuleRulesetRulesRuleRulesets

楷模

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

在主页上,用户可以添加/修改 aRuleset和添加/修改关联的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 Frameworkcreate()中所述,我为嵌套定义了一个自定义RulesetSerializer来处理多个对象的创建。根据Django一个应该能够

使用 add()、create() 或 set() 创建关系,只要您为任何必填字段指定 through_defaults。

执行时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.

我的模型和/或序列化程序设置是否有错误,或者 django 中是否有错误?

标签: djangodjango-rest-frameworkmany-to-manydjango-intermediate-table

解决方案


我误读了 django 文档。我在 django 2.1 上,并且仅在 2.2 中引入了直通字段。


推荐阅读