[Django] #32011: Error when calling add() on ManyRelatedManager with intermediary model

7 views
Skip to first unread message

Django

unread,
Sep 16, 2020, 12:05:52 PM9/16/20
to django-...@googlegroups.com
#32011: Error when calling add() on ManyRelatedManager with intermediary model
-------------------------------------+-------------------------------------
Reporter: Philipp | Owner: nobody
Maino |
Type: Bug | Status: new
Component: | Version: 2.1
Documentation | Keywords: ManyToMany,
Severity: Normal | ManyRelatedManager
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Django is not managing our databases for us, therefor I created the table
RulesetRuleMap to handle the ManyToMany relationship between Ruleset and
Rule: Each Ruleset can consist of multiple Rules and each Rule can be used
in multiple Rulesets.

**Models**
{{{
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'
}}}
**Serializers**
{{{
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
}}}
On a homepage the user can add/modify a Ruleset and add/modify the
assosiated Rules. On submission we receive a payload like this:
{{{
{
"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"
}
]
}
}}}
As described in [https://www.django-rest-framework.org/api-guide/relations
/#writable-nested-serializers/ DRF] I defined a custom create() for the
nested RulesetSerializer to handle the creation of multiple objects.
According to [https://docs.djangoproject.com/en/3.1/topics/db/models
/#extra-fields-on-many-to-many-relationships / Django] one should be able
to


----
use add(), create(), or set() to create relationships, as long as you
specify through_defaults for any required fields.
----

When executing ruleset.rules.add(*rules_storage, through_defaults={}) I
get the error

**''{TypeError}add() got an unexpected keyword argument
'through_defaults'''**

When executing ruleset.rules.add(*rules_storage) I get the error

**''{AttributeError}Cannot use add() on a ManyToManyField which specifies
an intermediary model.Use database_models.TcRulesetRuleMap's Manager
instead.''**

Is there a mistake in my model and/or serializer set up or is there a bug
in django?

--
Ticket URL: <https://code.djangoproject.com/ticket/32011>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Sep 16, 2020, 12:28:25 PM9/16/20
to django-...@googlegroups.com
#32011: Error when calling add() on ManyRelatedManager with intermediary model
-------------------------------------+-------------------------------------
Reporter: Philipp Maino | Owner: nobody
Type: Bug | Status: closed
Component: Documentation | Version: 2.1
Severity: Normal | Resolution: invalid
Keywords: ManyToMany, | Triage Stage:
ManyRelatedManager | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by felixxm):

* status: new => closed
* resolution: => invalid


Comment:

`through_defaults` was added in Django 2.2, please use
[https://docs.djangoproject.com/en/2.1/ documentation] for the version
you're using.

--
Ticket URL: <https://code.djangoproject.com/ticket/32011#comment:1>

Django

unread,
Sep 16, 2020, 12:51:13 PM9/16/20
to django-...@googlegroups.com
#32011: Error when calling add() on ManyRelatedManager with intermediary model
-------------------------------------+-------------------------------------
Reporter: Philipp Maino | Owner: nobody
Type: Bug | Status: closed
Component: Documentation | Version: 2.1
Severity: Normal | Resolution: invalid
Keywords: ManyToMany, | Triage Stage:
ManyRelatedManager | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Philipp Maino):

Replying to [comment:1 felixxm]:


> `through_defaults` was added in Django 2.2, please use
[https://docs.djangoproject.com/en/2.1/ documentation] for the version
you're using.

Hi @felixxm, I'm very happy if that's the problem at hand. I scaned over
the docs for 2.1 and didn't this difference:

**3.1**
You can also use **add()**, **create()**, or **set()** to create


relationships, as long as you specify through_defaults for any required
fields

**2.1**
Unlike normal many-to-many fields, you can’t use** add()**,** create()**,
or** set()** to create relationships:

--
Ticket URL: <https://code.djangoproject.com/ticket/32011#comment:2>

Reply all
Reply to author
Forward
0 new messages