Django-fr | Documentation | Sérialiser des objets Django

Django-fr

Documentation Django

Sérialiser des objets Django

Note

Cette API est en cours de modifications importantes et peut changer -- peut être drastiquement -- dans le futur.

Vous êtes prévenu.

Le framework de sérialisation de Django fourni un mécanisme pour "traduire" des objets Django dans d'autres formats. En général, ces autres formats sont de type texte et utilisé pour transporter des objets Django à travers le réseau, mais il est possible pour un sérialiseur de gérer n'importe quel format (de type texte ou non).

Sérialiser les données

Du point de vue haut niveau, sérialiser des données est une opération très simple:

from django.core import serializers
data = serializers.serialize("xml", SomeModel.objects.all())

Les arguments de la fonction serialize sont le format de sérialisation des données (voir Formats de sérialisation) et un QuerySet à sérialiser. (Actuellement, le second argument peut être n'importe quel itérateur qui génère des objets Django, mais ce sera quasiment toujours un QuerySet).

Vous pouvez tout aussi bien utiliser un object sérialiseur directement:

XMLSerializer = serializers.get_serializer("xml")
xml_serializer = XMLSerializer()
xml_serializer.serialize(queryset)
data = xml_serializer.getvalue()

C'est utile si vous avez besoin de sérialiser des données directement dans un objet pseudo-fichier (incluant un HTTPResponse):

out = open("file.xml", "w")
xml_serializer.serialize(SomeModel.objects.all(), stream=out)

Sous ensemble de champs

Si vous voulez seulement un sous ensemble de champs à sérialiser, vous pouvez renseigner l'argument fields du sérialiseur:

from django.core import serializers
data = serializers.serialize('xml', SomeModel.objects.all(), fields=('nom','taille'))

Dans cet exemple, seuls le attributs nom et taille de chaque modèles seront sérialisés.

Note

En fonction de votre modèle, vous vous rendrez compte qu'il n'est pas possible de désérialiser un modèle qui ne sérialise qu'une partie de ces champs. Si un objet sérialisé n'est pas renseigner avec tous les champs requis du modèle, le désérialiseur ne pourra pas sauvegarder d'instances désérialisées.

Désérialiser les données

Désérialiser les données est une opération tout aussi simple:

for obj in serializers.deserialize("xml", data):
    do_something_with(obj)

Comme vous pouvez le voir, la fonction deserialize prend le même argument de format, une chaîne de caractères ou un flux de données, et retourne un itérateur.

Cependant, ici les choses commencent à se compliquer. Les objets retournés par l'itérateur de deserialize ne sont pas de simple objets Django. A la place, ce sont des instances DeserializedObject spéciales qui encapsulent un objet alloué -- mais non sauvegardé -- et toutes les données relatives associées.

L'appel à DeserializedObject.save() sauvegarde l'objet en base de données.

Cela permet de s'assurer que le désérialisation est une opération non-destructive même les données de votre représentation sérialisée ne concordent pas avec ce qui est actuellement en base de données. En général, le travail réalisé avec les instances DeserializedObject ressemble à:

for deserialized_object in serializers.deserialize("xml", data):
    if object_should_be_saved(deserialized_object):
        deserialized_object.save()

En d'autres termes, l'usage général est de vérifier les objets désérialisés et de s'assurer qu'ils sont "appropriés" à sauvegarde avant de l'effectuer. Bien sur, si vous faîtes confiance à votre source de données vous pouvez tout simplement sauvegarder votre objet et passez votre chemin.

L'objet Django lui même peut être inspecté via deserialized_object.object`.

Formats de sérialisation

Django est "fourni" avec quelques sérialiseurs:

Identifier Information
xml Sérialise vers et depuis un dialecte XML simple.
json Sérialise depuis et vers JSON (en utilisant une version de simplejson fournie avec Django).
python Traduit vers et depuis de objets Python "simple" (lists, dicts, strings, etc.). Pas forcément très utile en lui même, mais utilisé comme base pour d'autres sérialiseurs.
yaml Sérialise vers YAML (Yet Another Markup Language). Ce sérialiseur est uniquement disponible si PyYAML est installé.

Notes pour les formats de sérialisation spécifiques

json

Si vous utilisez des données UTF-8 (ou tout autre encodage non ASCII) avec le sérialiseur JSON, vous devez passez ensure_ascii=False en tant que paramètre lors de l'appel à serialize(). Sinon, la sortie sera mal encodée.

Par exemple:

json_serializer = serializers.get_serializer("json")()
json_serializer.serialize(queryset, ensure_ascii=False, stream=response)

Le code source de Djando inclut le module simplejson. Gardez à l'esprit que lorsque vous utilisez ce module directement, toutes les données de Django ne peuvent pas être passées non modifiées à simplejson. En particulier, les objets de traduction paresseuse ont besoin d'un encodeur spécial écrit pour eux. Quelque chose comme cela devrait fonctionner:

from django.utils.functional import Promise
from django.utils.encoding import force_unicode

class LazyEncoder(simplejson.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Promise):
            return force_unicode(obj)
        return obj