Pergunta

Eu estou tentando fazer uma livesearch com Django e jQuery. O que eu tenho feito é fazer o javascript pedir alguns dados com a função getJSON, então eu configurar uma exibição em Django que retorna uma resposta JSON automatizado pelo serializer Django.

E isso funciona bem, ele retorna uma resposta json com o / tipo de conteúdo javascript texto. Para evitar o envio de todos os dados, (um monte que eu não preciso) eu fiz isso:

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

Mas, por exemplo, o campo 'gênero' é um campo ManyToMany, então é possível obter os valores de genre.all.0 por exemplo, e não apenas o ID gênero?

E o modelo tem uma função get_absolute _url, é possível incluir esta na resposta JSON, de que forma?

Então, eu acho que a minha pergunta é, é possível incluir coisas além dos dados de campo matérias na resposta JSON, se não, como você faria para resolver o meu problema?

Foi útil?

Solução 3

Eu descobri que a coisa mais simples foi a de não usar o serializador em tudo. Eu não sei porque eu não pensei nisso antes, mas eu usei apenas uma exibição de lista objeto genérico e mudou o tipo MIME para text / javascript e fez um modelo JSON insted de um modelo de html.

Muito simples, e de que maneira eu consegui obter todos os dados que eu queria na resposta JSON. Desta forma, você pode adicionar tudo o que você pode adicionar a um html modelo para uma resposta JSON, mesmo paginação.

Exemplo extracção da vista i criado:

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

Outras dicas

serialização JSON de Django é baseado em simplejson, que você pode usar diretamente e estender à vontade para lidar com qualquer tipo de objectos. Então você na maior parte tem duas opções aqui: construir manualmente uma lista de dicts com dados relevantes e passá-lo para simplejson.dumps () (que por padrão cordas de apoio, listas, dicts e numéricos), ou escrever seu próprio codificador JSON que sabe para serializar o conjunto de dados específico. FWIW, aqui está uma (não foi bem testado, mas trabalhou até agora) codificador JSON ciente modelo de Django:

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

Há um prático django terceiros app / serializer que lhe permitirá incluir dados extra. Ele também permite que você inclua relações modelo e excluir uma lista de campos.

Está disponível em http://code.google.com/p/wadofstuff/wiki/DjangoFullSerializers

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top