Ticket #2843: include_reverse_relations.3.diff

File include_reverse_relations.3.diff, 3.7 KB (added by c v t, 12 years ago)

I see that there is now a GSOC proposal including this functionality, but that plan involves a completely new serialization interface. 5 years later, Nikolaus's patch applies to trunk with only minimal changes (attached) -- is there any chance that, once it has tests and documentation, this approach could make it into trunk if / in case the GSOC idea doesn't work out?

  • django/core/serializers/xml_serializer.py

     
    55from django.conf import settings
    66from django.core.serializers import base
    77from django.db import models, DEFAULT_DB_ALIAS
     8from django.db.models.fields.related import OneToOneRel
    89from django.utils.xmlutils import SimplerXMLGenerator
    910from django.utils.encoding import smart_unicode
    1011from xml.dom import pulldom
     
    131132
    132133            self.xml.endElement("field")
    133134
     135    def handle_o2m_field(self, obj, field):
     136        if not isinstance(field.field.rel, OneToOneRel):
     137            self.xml.startElement("field", {
     138                "name" : field.get_accessor_name(),
     139                "rel"  : field.field.rel.__class__.__name__,
     140                "to"   : field.field.name,
     141            })
     142            for relobj in getattr(obj, field.get_accessor_name()).iterator():
     143                self.xml.addQuickElement("object", attrs={"pk" : str(relobj._get_pk_val())})
     144            self.xml.endElement("field")
     145
    134146    def _start_relational_field(self, field):
    135147        """
    136148        Helper to output the <field> element for relational fields
  • django/core/serializers/base.py

     
    3838        self.selected_fields = options.pop("fields", None)
    3939        self.use_natural_keys = options.pop("use_natural_keys", False)
    4040
     41        self.include_reverse_relations = options.get("include_reverse_relations", False)
     42        if self.options.has_key("include_reverse_relations"):
     43            del self.options["include_reverse_relations"]
     44
    4145        self.start_serialization()
    4246        for obj in queryset:
    4347            self.start_object(obj)
     
    5660                if field.serialize:
    5761                    if self.selected_fields is None or field.attname in self.selected_fields:
    5862                        self.handle_m2m_field(obj, field)
     63            if self.include_reverse_relations:
     64                for field in concrete_model._meta.get_all_related_objects():
     65                    self.handle_o2m_field(obj, field)
    5966            self.end_object(obj)
    6067        self.end_serialization()
    6168        return self.getvalue()
     
    102109        """
    103110        raise NotImplementedError
    104111
     112    def handle_o2m_field(self, obj, field):
     113        """
     114        Called to handle a OneToManyField.
     115        """
     116        raise NotImplementedError
     117
    105118    def getvalue(self):
    106119        """
    107120        Return the fully serialized queryset (or None if the output stream is
  • django/core/serializers/python.py

     
    77from django.conf import settings
    88from django.core.serializers import base
    99from django.db import models, DEFAULT_DB_ALIAS
     10from django.db.models.fields.related import OneToOneRel
    1011from django.utils.encoding import smart_unicode, is_protected_type
    1112
    1213class Serializer(base.Serializer):
     
    6465            self._current[field.name] = [m2m_value(related)
    6566                               for related in getattr(obj, field.name).iterator()]
    6667
     68    def handle_o2m_field(self, obj, field):
     69        if not isinstance(field.field.rel, OneToOneRel):
     70            self._current[field.get_accessor_name()] = [related._get_pk_val() for related in getattr(obj, field.get_accessor_name()).iterator()]
     71
    6772    def getvalue(self):
    6873        return self.objects
    6974
Back to Top