Opened 7 years ago

Closed 6 years ago

#15744 closed Cleanup/optimization (invalid)

serialization docs improvement

Reported by: choj Owned by: gumuz
Component: Documentation Version: 1.3
Severity: Normal Keywords: docs serialization
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no


In, the code fragment

return (self.first_name, self.last_name)

could be improved as a dict

return {'first name':self.first_name, 'last name':self.last_name}

to show how to enable fieldnames in the JSON output, rather than the default "naturalkey".

Attachments (1)

ticket15744.diff (504 bytes) - added by guyon.moree@… 7 years ago.
diff patch

Download all attachments as: .zip

Change History (8)

comment:1 Changed 7 years ago by Jacob

Easy pickings: set
Triage Stage: UnreviewedAccepted

Changed 7 years ago by guyon.moree@…

Attachment: ticket15744.diff added

diff patch

comment:2 Changed 7 years ago by gumuz

Owner: changed from nobody to gumuz
Status: newassigned
UI/UX: unset

comment:3 Changed 7 years ago by gumuz

Has patch: set

comment:4 Changed 7 years ago by gumuz

I was the one who included that patch, but forgot to register first.

comment:5 Changed 7 years ago by trez

Patch needs improvement: set

Just after the example, the doc says:
That method should always return a natural key tuple

I don't know if it's the example or the code but there is a mismatch.

comment:6 Changed 7 years ago by Christopher Medrela

Patch needs improvement: unset

Hm, there are some problems with natural key dictionaries connected with serialization as well as deserialization.

Consider the following file:

class PersonManager(models.Manager):
    def get_by_natural_key(self, *args, **kwargs):
        print args, kwargs # just for debug
        #return self.get(first_name=first_name, last_name=last_name) # previous version

class Person(models.Model):
    objects = PersonManager()

    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

    birthdate = models.DateField()

    def natural_key(self):
        return {'first name': self.first_name, 'last name': self.last_name} # after applying patch
        #return (self.first_name, self.last_name) # before applying patch

    class Meta:
        unique_together = (('first_name', 'last_name'),)

class Book(models.Model):
    name = models.CharField(max_length=100)
    author = models.ForeignKey(Person)

First, it works correctly with json, but not with xml. Produced xml by typing serialization.serialize('xml', Book.objects.all(), use_natural_keys=True) is

<?xml version="1.0" encoding="utf-8"?>
<django-objects version="1.0"><object pk="1" model=""><field type="CharField" name="name">My title</field><field to="polls.person" name="author" rel="ManyToOneRel"><natural>last name</natural><natural>first name</natural></field></object></django-objects>

You can see that the natural key is labels first name and last name instead of values!

I don't know if there is any problem with serializing with yaml.

There are problems with deserialization too. During deserialization PersonManager.get_by_natural_key is invoked, but args and kwargs given to this method are:

# these lines are printed by 3rd line of
(u'last name', u'first name') {} # xml
('last name', 'first name') {} # json

I guess that natural key should be tuple and intention of core developers was not using dictonaries. Accidentally json serialization works (that's undocumented feature :-) ). I suggest to close this ticket - django code is correct, doc is compatible, because it says about Person.natural_key

That method should always return a natural key tuple ...

and introduction to natural keys says

A natural key is a tuple of values that ...

Another question is if normal or unicode strings should be given to PersonManager.get_by_natural_key. Now, the unicode string is given during xml deserialization and normal string is given while json deserialization. Is it a bug?

comment:7 Changed 6 years ago by Tim Graham

Resolution: invalid
Status: assignedclosed

Agreed with krzysiumed's analysis. This doesn't look like it's a feature or at least a feature that works well enough to be documented.

Note: See TracTickets for help on using tickets.
Back to Top