4 votes

Comment envoyer une réponse HTTP au format Json dans les vues de classes génériques [Django] ?

J'ai sous-classé la classe Generic DetialView en views.py et j'essaie de trouver un moyen de renvoyer des données au format JSON en fonction d'un argument reçu dans l'url. Voici ce que j'ai essayé de faire...

# views.py
from django.views.generic import DetailView
from django.http import JsonResponse    

class ExtendedView(DetailView):
    context_object_name = 'post'
    model = StorageModel
    template_name='posts.html'

    def get_context_data(self, **kwargs):
        data = super(HacksViewPost, self).get_context_data(**kwargs)
        if bool(self.request.GET):
            data__ = JsonForm(request.GET)
            if data__.is_valid():
                json = data__.cleaned_data['json']
                if json == 'true':
                    return JsonResponse({'data': 'data'})
        return data

Mais cela m'a donné TypeError comme il se doit :

TypeError at /category/extended-slug/
context must be a dict rather than JsonResponse.

L'url qui active le ExtendedView la classe est :

/category/extended-slug?json=true

La question est donc de savoir comment je peux envoyer des données au format JSON à partir d'une classe de vue générique et s'il existe de meilleures façons d'y parvenir.

10voto

CommuSoft Points 6439

Je pense que tu l'as réparé au mauvais niveau. Le site get_context_data est utilisé par le get pour le rendre. Par conséquent, la fonction get_context_data L'objet a pas de le contrôle de ce qui est fait avec le résultat, afin de construire une réponse du serveur,

Vous pouvez toutefois corriger le get(..) comme une fonction :

class ExtendedView(DetailView):

    """A base view for displaying a single object."""
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        data = self.get_context_data(object=self.object)
        if self.request.GET:
            data__ = JsonForm(request.GET)
            if data__.is_valid():
                json = data__.cleaned_data['json']
                if json == 'true':
                    return JsonResponse({'data': data})
        return self.render_to_response(data)

Il en va de même pour post , put et d'autres demandes.

Si nous jetons un coup d'œil à la DetailView code source nous voyons :

class BaseDetailView(SingleObjectMixin, View):
    """A base view for displaying a single object."""
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        context = self.get_context_data(object=self.object)
        return self.render_to_response(context)

D'où la get(..) appelle le get_context_data(..) fonction. Mais il ne no renvoie immédiatement le résultat, il l'intègre dans une balise rendu réponse.

2voto

Dalvtor Points 874

Vous ne pouvez pas renvoyer un JsonResponse à l'intérieur de la get_context_data méthode. Le site get_context_data vous permet d'envoyer des informations supplémentaires (contexte) au modèle et doit renvoyer un message de type dict et non un JsonResponse .

Si vous voulez renvoyer un JsonResponse Faites-le dans le get o post de votre classe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X