Ticket #3661: serialize-properties.diff

File serialize-properties.diff, 8.6 KB (added by Øyvind Saltvik <oyvind.saltvik@…>, 18 years ago)

fixed for yaml, test for yaml, fix for invalid kwargs like fields and attributes passed yaml.dump and simplejson.dump

  • django/core/serializers/json.py

     
    1616    Convert a queryset to JSON.
    1717    """
    1818    def end_serialization(self):
    19         simplejson.dump(self.objects, self.stream, cls=DateTimeAwareJSONEncoder, **self.options)
     19        options = {}
     20        for option in self.options:
     21            if option in ['skipkeys', 'ensure_ascii', 'check_circular', 'allow_nan', 'cls', 'indent', 'encoding']:
     22                options[option] = self.options[option]
     23        simplejson.dump(self.objects, self.stream, cls=DateTimeAwareJSONEncoder, **options)
    2024       
    2125    def getvalue(self):
    2226        return self.stream.getvalue()
  • django/core/serializers/xml_serializer.py

     
    9797        for relobj in getattr(obj, field.name).iterator():
    9898            self.xml.addQuickElement("object", attrs={"pk" : str(relobj._get_pk_val())})
    9999        self.xml.endElement("field")
    100        
     100
     101    def handle_property(self, obj, attr):
     102        """
     103        Called to handle a model property
     104        """
     105        self.xml.startElement("property", {
     106            "name" : attr
     107        })
     108
     109        # Get a "string version" of the object's data (this is handled by the
     110        # serializer base class).  None is handled specially.
     111        value = self.get_string_value(obj, attr)
     112        if value is not None:
     113            self.xml.characters(str(value))
     114
     115        self.xml.endElement("property")
     116
     117   
    101118    def _start_relational_field(self, field):
    102119        """
    103120        Helper to output the <field> element for relational fields
     
    226243            inner_text.extend(getInnerText(child))
    227244        else:
    228245           pass
    229     return "".join(inner_text)
    230  No newline at end of file
     246    return "".join(inner_text)
  • django/core/serializers/base.py

     
    2929
    3030        self.stream = options.get("stream", StringIO())
    3131        self.selected_fields = options.get("fields")
     32        self.serialize_attributes = options.get("attributes")
    3233
    3334        self.start_serialization()
    3435        for obj in queryset:
     
    4243                else:
    4344                    if self.selected_fields is None or field.attname[:-3] in self.selected_fields:
    4445                        self.handle_fk_field(obj, field)
     46            if self.serialize_attributes:
     47                attrdict = obj.__class__.__dict__
     48                for attr in attrdict:
     49                    if isinstance(attrdict[attr], property):
     50                        self.handle_property(obj, attr)
    4551            for field in obj._meta.many_to_many:
    4652                if self.selected_fields is None or field.attname in self.selected_fields:
    4753                    self.handle_m2m_field(obj, field)
     
    5763            value = getattr(obj, field.name).strftime("%Y-%m-%d %H:%M:%S")
    5864        elif isinstance(field, models.FileField):
    5965            value = getattr(obj, "get_%s_url" % field.name, lambda: None)()
     66        elif isinstance(field, models.Field):
     67            value = field.flatten_data(follow=None, obj=obj).get(field.name, "")
    6068        else:
    61             value = field.flatten_data(follow=None, obj=obj).get(field.name, "")
     69            value = getattr(obj, field)
    6270        return str(value)
    6371
    6472    def start_serialization(self):
  • django/core/serializers/pyyaml.py

     
    1818    Convert a queryset to YAML.
    1919    """
    2020    def end_serialization(self):
    21         yaml.dump(self.objects, self.stream, **self.options)
     21        options = {}
     22        for option in self.options:
     23            if option in ['default_style', 'default_flow',
     24                'canonical', 'indent', 'cls', 'indent',
     25                'width','allow_unicode','line_break',
     26                'encoding','explicit_start', 'explicit_end',
     27                'version', 'tags']:
     28
     29                options[option] = self.options[option]
     30
     31        yaml.dump(self.objects, self.stream, **options)
    2232       
    2333    def getvalue(self):
    2434        return self.stream.getvalue()
  • django/core/serializers/python.py

     
    2121        pass
    2222       
    2323    def start_object(self, obj):
    24         self._current = {}
     24        self._current = {'fields': {}, 'properties': {}}
    2525       
    2626    def end_object(self, obj):
    27         self.objects.append({
     27
     28        object = {
    2829            "model"  : str(obj._meta),
    2930            "pk"     : str(obj._get_pk_val()),
    30             "fields" : self._current
    31         })
     31            "fields" : self._current['fields']
     32        }
     33        if self._current['properties']:
     34            object.update({'properties':  self._current['properties']})
     35
     36        self.objects.append(object)
    3237        self._current = None
    3338       
    3439    def handle_field(self, obj, field):
    35         self._current[field.name] = getattr(obj, field.name)
     40        self._current['fields'][field.name] = getattr(obj, field.name)
    3641       
    3742    def handle_fk_field(self, obj, field):
    3843        related = getattr(obj, field.name)
    3944        if related is not None:
    4045            related = related._get_pk_val()
    41         self._current[field.name] = related
     46        self._current['fields'][field.name] = related
    4247   
    4348    def handle_m2m_field(self, obj, field):
    44         self._current[field.name] = [related._get_pk_val() for related in getattr(obj, field.name).iterator()]
    45    
     49        self._current['fields'][field.name] = [related._get_pk_val() for related in getattr(obj, field.name).iterator()]
     50
     51    def handle_property(self, obj, attr):
     52        self._current['properties'][attr] = getattr(obj, attr)
     53 
    4654    def getvalue(self):
    4755        return self.objects
    4856
  • tests/modeltests/serializers/models.py

     
    4040class AuthorProfile(models.Model):
    4141    author = models.OneToOneField(Author)
    4242    date_of_birth = models.DateField()
     43
     44    def is_cool(self):
     45        return True
     46    is_cool = property(is_cool)
    4347   
    4448    def __str__(self):
    4549        return "Profile of %s" % self.author
     
    130134# pk identifier.
    131135>>> profile = AuthorProfile(author=joe, date_of_birth=datetime(1970,1,1))
    132136>>> profile.save()
    133 
    134137>>> json = serializers.serialize("json", AuthorProfile.objects.all())
    135138>>> json
    136139'[{"pk": "1", "model": "serializers.authorprofile", "fields": {"date_of_birth": "1970-01-01"}}]'
    137140
     141>>> json = serializers.serialize("json", AuthorProfile.objects.all(), attributes=True)
     142>>> json
     143'[{"pk": "1", "model": "serializers.authorprofile", "properties": {"is_cool": true}, "fields": {"date_of_birth": "1970-01-01"}}]'
     144
    138145>>> for obj in serializers.deserialize("json", json):
    139146...     print obj
    140147<DeserializedObject: Profile of Joe>
    141148
     149# Optionally serialize model properties using, attributes=True, this is also affected by the fields option
     150>>> xml = serializers.serialize("xml", AuthorProfile.objects.all(), attributes=True)
     151>>> xml
     152'<?xml version="1.0" encoding="utf-8"?>\\n<django-objects version="1.0"><object pk="1" model="serializers.authorprofile"><field type="DateField" name="date_of_birth">1970-01-01</field><property name="is_cool">True</property></object></django-objects>'
     153
     154>>> yaml = serializers.serialize("yaml", AuthorProfile.objects.all(), attributes=True)
     155>>> yaml
     156"- fields: {date_of_birth: 1970-01-01}\\n  model: serializers.authorprofile\\n  pk: '1'\\n  properties: {is_cool: true}\\n"
     157
    142158# Objects ids can be referenced before they are defined in the serialization data
    143159# However, the deserialization process will need to be contained within a transaction
    144160>>> json = '[{"pk": "3", "model": "serializers.article", "fields": {"headline": "Forward references pose no problem", "pub_date": "2006-06-16 15:00:00", "categories": [4, 1], "author": 4}}, {"pk": "4", "model": "serializers.category", "fields": {"name": "Reference"}}, {"pk": "4", "model": "serializers.author", "fields": {"name": "Agnes"}}]'
Back to Top