#11310 closed (worksforme)
Unable to serialize ManyToMany fields with "trough"
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Core (Serialization) | Version: | dev |
Severity: | Keywords: | ManyToMany | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Problem is, that ManyToMany field with intermediate table is ignored in PythonSerializer. This patch should fix it.
http://code.djangoproject.com/svn/django/trunk/django/core/serializers/python.py 59,61c59,60 < if field.creates_table: < self._current[field.name] = [smart_unicode(related._get_pk_val(), strings_only=True) < for related in getattr(obj, field.name).iterator()] --- > self._current[field.name] = [smart_unicode(related._get_pk_val(), strings_only=True) > for related in getattr(obj, field.name).iterator()]
Change History (6)
comment:1 by , 15 years ago
Component: | Uncategorized → Serialization |
---|---|
Has patch: | set |
Keywords: | ManyToMany added |
comment:2 by , 15 years ago
Resolution: | → worksforme |
---|---|
Status: | new → closed |
comment:3 by , 15 years ago
Resolution: | worksforme |
---|---|
Status: | closed → reopened |
Version: | 1.0 → SVN |
Hi,
look at this example:
class A(models.Model): foo = models.CharField(max_length=32) # b = models.ManyToManyField('B', through='A_B') b = models.ManyToManyField('B') class B(models.Model): bar = models.CharField(max_length=32) class A_B(models.Model): a = models.ForeignKey('A') b = models.ForeignKey('B')
Then i run:
>>> from django.core.serializers import serialize >>> serialize('python', A.objects.all()) [{'pk': 1L, 'model': u'testapp.a', 'fields': {'foo': u'eeeee', 'b': [1L]}}]
This is OK.
Now I change models to this:
class A(models.Model): foo = models.CharField(max_length=32) b = models.ManyToManyField('B', through='A_B') # b = models.ManyToManyField('B') class B(models.Model): bar = models.CharField(max_length=32) class A_B(models.Model): a = models.ForeignKey('A') b = models.ForeignKey('B')
I serialize it:
>>> from django.core.serializers import serialize >>> serialize('python', A.objects.all()) [{'pk': 1L, 'model': u'testapp.a', 'fields': {'foo': u'eeeee'}}]
'b' is missing in output...
comment:4 by , 15 years ago
Resolution: | → worksforme |
---|---|
Status: | reopened → closed |
Your example code is explicitly serializing objects of type A. However, when you have a through relationship, you need to serialize the A_B model separately, since that model could contain extra data.
When you don't have a through model, there isn't an actual model representing the through relationship., so the m2m data is included on the A model as a list of related objects.
comment:5 by , 15 years ago
Thanks for explanation. I was migrating some models without 'through' to use 'through' and serialization behaviour was changed. I made a wraparound of this using custom serializer:
class CustomSerializer(python.Serializer): def handle_m2m_field(self, obj, field): field.creates_table = True super(XMLRPCSerializer, self).handle_m2m_field(obj, field)
Yeah, it's ugly, but it works ;-)
The test suite contains a test to validate that serialization works for m2m with a through field (see the [http://code.djangoproject.com/browser/django/trunk/tests/regressiontests/m2m_through_regress/models.py regressiontests/m2m_through_regress tests). Without a test case showing a specific failure case I'm going to mark this worksforme.