2010-02-07 7 views
5

Estoy dando los toques finales a una API que he escrito para una aplicación de Django que utiliza django-pistón. La API puede buscar por solicitud o dirección IP que son Request o IPAddress instancias respectivamente. Cada solicitud puede tener 1 o más IPAddress asociados.Django Piston: ¿Cómo puedo excluir campos anidados de los resultados del controlador? ¿Es posible?

Entonces, por ejemplo, tengo una llamada API que mostrará todos los objetos IPAddress que coincidan con un estado de actividad de "activo", "inactivo" o "todo" (para cualquiera). El Request al que está asociada cada instancia IPAddress está disponible como IPAddress.request.

El problema que tengo es que Request.inputter es una clave externa a la instancia User de la persona que aprovisionó la solicitud. Cuando se devuelven mis resultados del controlador que he creado para esta llamada API, se muestran todos los campos de la instancia User, incluido password.

Esto es malo; No quiero esto.

Así que aquí es mi manejador:

class SearchByIPStatusHandler(BaseHandler): 
    model = IPAddress 
    allowed_methods = ('GET',) 
    anonymous = AnonymousIPHandler 

    def read(self, request, status): 
     """ 
     Returns IP addresses based on activity status. 
     Status: 'active', 'inactive', 'all' 

     """ 
     if status == 'all': 
      return self.model.objects.all() 
     else: 
      active = True if (status=='active') else False 
      return self.model.objects.filter(active=active) 

Y aquí es un ejemplo de los resultados de /api/show/all/:

<response> 
    <resource> 
    <updated>2010-02-05 17:08:53.651729</updated> 
    <expires>2010-02-12 17:08:23</expires> 
    <created>2010-02-05 17:08:53.625318</created> 
    <nexthop>255.255.255.255</nexthop> 
    <netmask>255.255.255.254</netmask> 
    <address>2.4.6.80/31</address> 
    <active>True</active> 
    <id>4</id> 
    <request> 
     <updated>2010-02-05 17:08:53.382381</updated> 
     <created>2010-02-05 17:08:53.382313</created> 
     <expires>2010-02-12 17:08:23</expires> 
     <incident>20100212-badthings-01</incident> 
     <reason>bad things happened</reason> 
     <inputter> 
     <username>jathan</username> 
     <first_name>Jathan</first_name> 
     <last_name>McCollum</last_name> 
     <is_active>True</is_active> 
     <email>[email protected]</email> 
     <is_superuser>True</is_superuser> 
     <is_staff>True</is_staff> 
     <last_login>2010-02-05 18:55:51.877746</last_login> 
     <password>[ENCRYPTED STRING I REDACTED]</password> 
     <id>1</id> 
     <date_joined>2010-01-28 09:56:32</date_joined> 
     </inputter> 
     <requester>joeuser</requester> 
     <active>True</active> 
    </request> 
    </resource> 
</response> 

Todo lo que realmente quiero en los resultados es el inputter.username, no todo el otras cosas. He intentado varias iteraciones de implementar un atributo exclude en el controlador en vano. Si a saltar todo el campo de petición, que funciona bien, así:

En manejador:

exclude = ('request',) 

que se traduce en:

<response> 
    <resource> 
    <updated>2010-02-05 17:08:53.651729</updated> 
    <expires>2010-02-12 17:08:23</expires> 
    <created>2010-02-05 17:08:53.625318</created> 
    <nexthop>255.255.255.255</nexthop> 
    <netmask>255.255.255.254</netmask> 
    <address>2.4.6.80/31</address> 
    <active>True</active> 
    <id>4</id> 
    </resource> 
</response> 

Sin embargo, estos resultados no son también lo que quiero .

Así que, finalmente, mi pregunta:

campos ¿Cómo puedo excluir anidados de resultados de controlador? ¿Es posible?

he intentado varias iteraciones de los siguientes, todos los cuales o bien no tienen ningún resultado o resultados no deseados:

# try to exclude request.inputter 
exclude = (('request', ('inputter',),)) 

# try to exclude request.inputter.password 
exclude = (('request', ('inputter', ('password',)))) 

Asumo que estoy mal entendido o mal uso de la forma en que las exclusiones de campo se llevan a cabo en este contexto , por lo que cualquier aclaración sobre este tema es muy apreciada.

Respuesta

3

Puede obtener el resultado deseado especificando los campos deseados a través de la cláusula fields = del controlador.

campos de modelos procedentes de las claves externas se pueden especificar como esto:

('foreign_model_field', ('nested_field1', 'nested_field2')) 

En su caso, el siguiente debe funcionar (algunos de sus campos dejados de lado por razones de brevedad):

fields = ('updated', 'expires', 'created', 
    ('request', ('incident', 'reason', ('inputter', ('username',))))) 
+0

Eso sí funciona. ¡Gracias por la respuesta! Más tedioso de lo que esperaba (especialmente cuando inevitablemente tendré que duplicar esto en múltiples manejadores), ¡pero una solución es una solución! – jathanism

3

¿Puedes intentar usar incluir en lugar de excluir? P.ej.

include = (('request', ('inputter', ('username', 'therestofthefields')))) 

No recuerdo si escribía exclude ser tan versátil como include.

Además, el grupo de django-piston Google es donde discutimos la mayoría de las cosas, puede tener más éxito haciendo esta pregunta allí.

+0

Gracias por interviniendo, Jesper. Voy a engañar esto en la lista de correo. – jathanism

Cuestiones relacionadas