Json View - Django class-based generic views - III

Reaproveitando um ListView e serializando a saída, transformando-a em Json

Introdução

# Se quer saber primeiro sobre class based generic views e esta série de artigos que estou fazendo, basta ler este trecho do primeiro artigo da série.

Vamos imaginar que você precisa serializar a Response de uma view tua para utilizar os dados e trabalhá-los com Ajax, e/ou para criar uma API, ou seja lá qual for o motivo, se você usa as class based generic views do Django fica mais fácil e elegante. Neste artigo veremos um exemplo simples de como fazê-lo.

Reforçando novamente que tomo por base o código do repositório que criei no github para os exemplos.

Estendendo uma ListView para criarmos nossa JsonView

O arquivo views.py, ou em nosso caso list_and_detail.py, tem uma view que lista os objetos de uma "lista de reprodução", como abaixo:

from django.views.generic importListView
from app_exemplo.models importListaDeReproducao

class ListasDeReproducao(ListView):
    model = ListaDeReproducao

Com o exemplo acima teremos uma lista de objetos de ListaDeReproducao , porém o retorno será em text/html do modo convencional, em que precisamos renderizar um template e tudo mais.

Para aproveitarmos possíveis comportamentos, personalizações e/ou mesmo as definições dos atributos já contidos em ListaDeReproducao vamos estender esta view e fazer a modificação no método get(self, request, *args, **kwargs) para termos um response application/json.

Em views.json (json.py) eu tenho isto:

# coding: utf-8
from django.http import HttpResponse
from django.core import serializers
from list_and_detail import ListasDeReproducao

class ListasDeReproducaoJson(ListasDeReproducao):
    context_object_name = 'listas_de_reproducao'

    def get(self, request, *args, **kwargs):
        data = serializers.serialize("json", self.get_queryset())
        return HttpResponse(data, content_type='application/json')

O conteúdo desta resposta é o retorno de self.get_queryset() já serializado no formato JSON. Algo como:

[
    {
        "pk":1,
        "model":"app_exemplo.listadereproducao",
        "fields":{
            "modificado":"2010-03-13 12:12:45",
            "audios":[
                1,
                2,
                3
            ],
            "criado":"2010-01-26 15:25:26",
            "titulo":"Animiais",
            "slug":"Animais",
            "descricao":"Alguns efeitos sonoros de animais."
        }
    },
    {
        "pk":2,
        "model":"app_exemplo.listadereproducao",
        "fields":{
            "modificado":"2010-05-30 08:16:53",
            "audios":[
                4,
                5,
                6,
                7
            ],
            "criado":"2010-01-05 14:12:28",
            "titulo":"Clicks",
            "slug":"clicks",
            "descricao":"Efeitos sonoros de CLICKs."
        }
    },
    // ...
]

Para um exemplo isto serve, mas talvez você realmente queira personalizar isto antes de transformá-lo em Json. Por exemplo se você quer serializar um queryset de usuários, dependendo de como sua query foi composta, pode trazer o campo 'senha' e, talvez, você queira omití-lo deste retorno. Contudo creio que não haverá grandes problemas para fazer isto, uma vez que com self.get_queryset() você consegue manipular bem estes resultados, antes de serializá-los.

Conclusão

Bem, este foi um exemplo simples, em um outro artigo creio que farei algo como retornar o Json e trabalhar ele com Jquery.

Extra:

Se você quisesse, ao invés de Json, retornar um XML, bastaria modificar duas simples coisas, neste simples exemplo, é claro:

# ...
serializers.serialize("xml", self.get_queryset())
return HttpResponse(data, content_type='application/xml')

blog comments powered by Disqus