#14226: Bug in dumpdata dependency calculation involving ManyToManyFields ---------------------------+------------------------------------------------ Reporter: aneil | Owner: nobody Status: new | Milestone: Component: Serialization | Version: 1.2 Keywords: | Stage: Unreviewed Has_patch: 0 | ---------------------------+------------------------------------------------ The manage.py dumpdata command incorrectly interprets !ManyToMany relationships as dependencies of the model that declares them (rather than the other way around).
In the example below are 5 models - User, Tag and Posting, where both User and Posting have M2M relationships to Tag via !UserTag and !PostingTag, respectively. This should be serializable. Here are the actual dependencies: {{{ User: None Tag: None Posting: User PostingTag: Posting, Tag UserTag: User, Tag }}} However, dumpdata fails with this error: Error: Can't resolve dependencies for main.Posting, main.!PostingTag, main.Tag, main.User, main.!UserTag in serialized app list. {{{ from django.db.models import Model,CharField,ForeignKey,ManyToManyField,TextField,DateTimeField class User(Model): username = CharField(max_length=20) password = CharField(max_length=20) topics = ManyToManyField("Tag",through="UserTag") def natural_key(self): return (self.username,) class Posting(Model): user = ForeignKey(User) text = TextField() time = DateTimeField() def natural_key(self): return (self.user.username,self.time) natural_key.dependencies=['main.User'] class Tag(Model): name = CharField(max_length=20) postings = ManyToManyField(Posting,through="PostingTag") def natural_key(self): return (self.name,) class PostingTag(Model): tag = ForeignKey(Tag) posting = ForeignKey(Posting) def natural_key(self): return (self.tag.natural_key(),self.posting.natural_key()) class UserTag(Model): user = ForeignKey(User) tag = ForeignKey(Tag) def natural_key(self): return (self.tag.natural_key(),self.user.natural_key()) }}} The reason this occurs is invalid logic in django/core/management/commands/dumpdata.py in lines 152-155. Here is the relevant code & context: {{{ 145 # Now add a dependency for any FK or M2M relation with 146 # a model that defines a natural key 147 for field in model._meta.fields: 148 if hasattr(field.rel, 'to'): 149 rel_model = field.rel.to 150 if hasattr(rel_model, 'natural_key'): 151 deps.append(rel_model) 152 for field in model._meta.many_to_many: 153 rel_model = field.rel.to 154 if hasattr(rel_model, 'natural_key'): 155 deps.append(rel_model) 156 model_dependencies.append((model, deps)) }}} Lines 152-155 treat M2M relations like FK relations. This is incorrect. A Model named by an FK is a dependency, however, the model named by an M2M is not. The fix requires adding the M2M *table* to the model_list, and processing its dependencies accordingly. I've attached a simple test project that demonstrates the problem. -- Ticket URL: <http://code.djangoproject.com/ticket/14226> Django <http://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To post to this group, send email to django-upda...@googlegroups.com. To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.