2009-10-23 12 views
18

estoy serializar un montón de objetos con:Quitar de objetos serializados django

json = serializers.serialize("json", objects, fields=('name', 'country')) 

No he incluido 'pk' en mi lista de campos, pero el JSON producido incluye una clave principal con cada serializado objeto. No quiero que mi API exponga las claves principales al público en general.

Si no se corta la salida JSON, ¿cuál es la forma correcta de decir serializers.serialze() que no se incluye la clave principal?

+0

@ Josh Reich ¿Qué le termina haciendo en este caso? Hay un ticket que habla de ello @ http://code.djangoproject.com/ticket/4656 – orokusaki

+0

Terminé llamando a simplejson manualmente –

Respuesta

16

Terminé trabajando alrededor de esto 'manualmente' lograr lo que quería usar el simplejson serializador subyacente:

from django.utils import simplejson 
json = simplejson.dumps([{'name': o.name, 
          'country': o.country} for o in objects]) 

Un poco más de mecanografía, pero funciona.

+0

es una buena solución si solo quieres descargar algunos datos a json y no te preocupan los FK. –

+0

@Josh Es mucho más código si tienes 28 métodos que usan 5 modelos en una API. – orokusaki

+0

Lo he usado. Pero es una molestia cuando usas esto en varias vistas. Lo mejor es usar los serializadores de Django. La última respuesta tiene un enlace a una pregunta relacionada, que explica cómo eliminar los campos pk y model de los objetos que genera. – Dmitry

0

No malgastamos nuestro tiempo tratando de "desinfectar" las PK. Cuando producimos un registro JSON, el PK está allí, y el usuario puede ignorarlo si lo desea. No pueden hacer nada con la información, así que es un desorden.

Ninguna de nuestras interfaces de servicios web permite que alguien nos devuelva una PK. Realizamos búsquedas POST, PUT y DELETE en otros campos, pero no en PK.

El HTML, sin embargo, muestra la URL de PK todo el tiempo. Permite a las personas marcar las páginas como favoritas.

+7

Muchas compañías asumen que no hay información contenida en las claves primarias secuenciales. Si tiene sus controles de acceso bloqueados, no tiene de qué preocuparse, ¿no? Incorrecto. Por lo menos, revelar los identificadores secuenciales proporciona una excelente manera para que los competidores realicen un seguimiento de su crecimiento. Existe una industria considerable basada simplemente en encontrar identificaciones secuenciales y estimaciones de crecimiento de ventas. –

+0

Puede abordar su problema mediante el uso de UUID en lugar de ID secuenciales, por lo que exponerlos a públicos no proporcionará ninguna información para los competidores. –

+0

Considere también el texto adicional que se envía a cada usuario cuando se incluye el modelo pk. Este es el ancho de banda que podría guardarse claramente (especialmente al enviar esto a un usuario móvil). – shaond

3

Aunque esta es una pregunta antigua, es probable que alguien más la encuentre en una búsqueda en Google.

Desafortunadamente, el serializador django ofrece bastante poca personalización como la que definió. Mi solución, si sabes que utilizarás una gran cantidad de serialización para tu proyecto, fue simplemente copiar la serialización de django a mi propio proyecto y hacer algunos pequeños cambios. Esto no es ideal, pero cumple su función. Específicamente, para eliminar las de PK, hay una línea en start_object (self, obj):

self.xml.startElement("object", { 
     "pk" : smart_unicode(obj._get_pk_val()), 
     "model" : smart_unicode(obj._meta), 
    }) 

Extracción de la línea "PK" debería solucionarlo. Es un truco algo sucio, ya que si mejoran esto más adelante puede requerir algunos cambios en sus puntos de vista, pero para mí esta fue la forma más fácil de evitar las limitaciones.

Espero que esto ayude a alguien.

7

También puede anular JSON serializador como se explica aquí: Override Django Object Serializer to get rid of specified model

from django.core.serializers.json import Serializer, DjangoJSONEncoder 
from django.utils import simplejson 

import logging 

class MySerializer(Serializer): 
    def end_serialization(self): 
     cleaned_objects = [] 

     for obj in self.objects: 
      del obj['pk'] 
      cleaned_objects.append(obj) 

     simplejson.dump(cleaned_objects, self.stream, cls=DjangoJSONEncoder, **self.options) 
+0

¡Gracias! ¡La respuesta de esa pregunta ayudó mucho! – Dmitry

0

La fea (pero trabajando) forma:

data_tmp = data.split('{') 
#Gets all the data after fields 
response = "[{"+data_tmp[2].replace("}}","}",1) 
8

lo que Josh hizo pero al revés:

data = json.loads(json_string) 

for d in data: 
    del d['pk'] 
    del d['model'] 

data = json.dumps(data) 

De esta forma, no tiene que preocuparse por actualizar el código cuando agrega más campos en el futuro.

1

Tuve el mismo problema, así que creé mi propio Serializer, herencia de Serializer de Django. Me gustaría solo los datos del campo, por lo tanto, sobrescribo el método get_dump_object y agregué el campo PK.

from django.core.serializers.json import Serializer 


class JSONSerializer(Serializer): 
    def get_dump_object(self, obj): 
     self._current[obj._meta.pk.name] = obj._get_pk_val() 
     return self._current 

Y llama:

output = JSONSerializer().serialize(queryset) 
Cuestiones relacionadas