Opened 11 years ago
Last modified 11 years ago
#21763 closed Cleanup/optimization
Misleading Error: 'ManyRelatedManager' object has no attribute 'add' — at Version 2
Reported by: | anonymous | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | yes | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description (last modified by )
Synopsis
When defining a many-to-many relationship using a 'through' model, the 'add' and 'create' methods are not available, for good reason. However, rather than failing with a helpful exception directing the user to use the through model, the relevant ManyRelatedManager is simply missing its usual methods, raising a misleading AttributeError instead.
Expected Behavior
IMO, it would be more helpful, and possibly somewhat more Pythonic, to produce a type of exception that directs the user to use the through model. This correctly indicates the source of the problem, and doesn't require much additional monkeying about since the object already has to know of the need to use one as it is now, since it must be instantiated with no add/create methods.
Actual Behavior
The ManyRelatedManager is created missing two of its usual methods, raising an AttributeError if they are called. This is misleading[1] and can result in several wasted minutes making sure the method name and object is correct, consulting documentation, and so on.
Steps to Reproduce
- Create two simple models.
- Link them with a third model defined as a 'through' relation.
- Call add or create on one of the ManyRelatedManagers.
Example:
# in models.py from django.db import models class Person(models.Model): pass class Group(models.Model): members = models.ManyToManyField(Person, through='Membership') class Membership(models.Model): person = models.ForeignKey(Person) group = models.ForeignKey(Group) date_joined = models.DateField(auto_now_add=True)
# on shell >>> from testing.models import * >>> group = Group.objects.create() >>> person = Person.objects.create() >>> group.members.add(person) Traceback (most recent call last): File "<console>", line 1, in <module> AttributeError: 'ManyRelatedManager' object has no attribute 'add'}}} [1] See, e.g., [this StackOverflow question](http://stackoverflow.com/q/8095813/2588818) and the related top comment/answer.
Change History (2)
comment:1 by , 11 years ago
comment:2 by , 11 years ago
Component: | Uncategorized → Database layer (models, ORM) |
---|---|
Description: | modified (diff) |
Easy pickings: | set |
Needs tests: | set |
Triage Stage: | Unreviewed → Accepted |
Type: | Uncategorized → Cleanup/optimization |
Version: | 1.5 → master |
I agree that raising a more significant
AttributeError
wouldn't hurt.