Comment inclure des données supplémentaires dans la réponse du sérialiseur Django?

StackOverflow https://stackoverflow.com/questions/413603

  •  03-07-2019
  •  | 
  •  

Question

J'essaie de mener une recherche en direct avec Django et jQuery. Ce que j’ai fait, c’est que le javascript demande des données avec la fonction getJSON, puis j’ai configuré une vue dans Django qui renvoie une réponse JSON automatisée par le sérialiseur Django.

Et cela fonctionne bien, il renvoie une réponse json avec le type de contenu text / javascript. Pour éviter d'envoyer toutes les données, (beaucoup dont je n'ai pas besoin), j'ai fait ceci:

response.write (serializers.serialize ("json", soknad_list, fields = ('nom', 'image', 'genre')))

Mais par exemple, le champ 'genre' est un champ manyToMany, est-il possible d'obtenir les valeurs de genre.all.0 par exemple, et pas seulement l'ID de genre?

Et le modèle a une fonction get_absolute _url , est-il possible de l'inclure dans la réponse JSON, le cas échéant, comment?

Donc, je suppose que ma question est la suivante: est-il possible d'inclure d'autres éléments que les données de champ brutes dans la réponse JSON? Sinon, comment procéderiez-vous pour résoudre mon problème?

Était-ce utile?

La solution 3

J'ai découvert que le plus simple était de ne pas utiliser le sérialiseur du tout. Je ne sais pas pourquoi je n'y avais pas pensé auparavant, mais je viens d'utiliser une vue de liste d'objets génériques et de changer le type MIME en text / javascript et de créer un modèle JSON à partir d'un modèle HTML.

Très simple, et de cette façon j'ai réussi à obtenir toutes les données que je voulais dans la réponse JSON. De cette façon, vous pouvez ajouter tout ce que vous pouvez ajouter à un modèle html dans une réponse JSON, même en paginant.

Exemple d'extraction de la vue que j'ai créée:

    return object_list (request, queryset = object_list, template_name = 'search / results.js', template_object_name = 'result', paginate_by = 12, mimetype = 'text / javascript')

Autres conseils

La sérialisation JSON de Django est basée sur simplejson, que vous pouvez utiliser directement et étendre à volonté pour gérer tout type d’objets. Donc vous avez principalement deux options ici: soit construire manuellement une liste de dict avec les données pertinentes et la transmettre à simplejson.dumps () (qui supporte par défaut les chaînes, listes, dict et numics), ou écrire votre propre pour sérialiser votre jeu de données spécifique. FWIW, voici un encodeur JSON jango compatible avec le modèle Django (pas bien testé mais qui a fonctionné jusqu’à présent):

from django.utils import simplejson
from django.utils import datetime_safe
from django.utils.functional import Promise
from django.utils.translation import force_unicode
from django.utils.encoding import smart_unicode
from django.core.serializers.json import DjangoJSONEncoder

class ModelJSONEncoder(DjangoJSONEncoder):
    """
    (simplejson) DjangoJSONEncoder subclass that knows how to encode fields.

    (adated from django.serializers, which, strangely, didn't
     factor out this part of the algorithm)
    """
    def handle_field(self, obj, field):
        return smart_unicode(getattr(obj, field.name), strings_only=True)

    def handle_fk_field(self, obj, field):
        related = getattr(obj, field.name)
        if related is not None:
            if field.rel.field_name == related._meta.pk.name:
                # Related to remote object via primary key
                related = related._get_pk_val()
            else:
                # Related to remote object via other field
                related = getattr(related, field.rel.field_name)
        return smart_unicode(related, strings_only=True)

    def handle_m2m_field(self, obj, field):
        if field.creates_table:
            return [
                smart_unicode(related._get_pk_val(), strings_only=True)
                for related
                in getattr(obj, field.name).iterator()
                ]

    def handle_model(self, obj):
        dic = {}
        for field in obj._meta.local_fields:
            if field.serialize:
                if field.rel is None:
                    dic[field.name] = self.handle_field(obj, field)
                else:
                    dic[field.name] = self.handle_fk_field(obj, field)
        for field in obj._meta.many_to_many:
            if field.serialize:
                dic[field.name] = self.handle_m2m_field(obj, field)
        return dic

    def default(self, obj):
        if isinstance(o, Promise):
            return force_unicode(o)

        if isinstance(obj, Model):
            return self.handle_model(obj)

        return super(ModelJSONEncoder, self).default(obj)

HTH

Il existe une application / un sérialiseur tiers django pratique qui vous permettra d’inclure des données supplémentaires. Il vous permet également d’inclure des relations de modèle et d’exclure une liste de champs.

disponible sur http://code.google.com/p/wadofstuff/wiki/DjangoFullSerializers

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top