2010-02-07 5 views
5

Je suis en train de mettre la touche finale à une API que j'ai écrite pour une application Django utilisant django-piston. L'API est capable de rechercher par requête ou adresse IP qui sont Request ou IPAddress respectivement. Chaque demande peut avoir une 0 ou plus IPAddress associée. Ainsi, par exemple, j'ai un appel d'API qui montrera tous les objets IPAddress correspondant à un statut d'activité "actif", "inactif", ou "tout" (pour l'un ou l'autre). Le Request auquel est associée chaque instance IPAddress est disponible sous la forme IPAddress.request.Django Piston: Comment puis-je exclure les champs imbriqués des résultats du gestionnaire? Est-ce même possible?

Le problème que j'ai est que Request.inputter est une clé étrangère à l'instance User de la personne qui a provisionné la demande. Lorsque mes résultats sont renvoyés par le gestionnaire que j'ai créé pour cet appel d'API, tous les champs de l'instance User sont affichés, y compris password.

Ceci est mauvais; Je ne veux pas ça.

Voici donc mon gestionnaire:

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) 

Et voici un exemple des résultats 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> 

Tout ce que je veux vraiment dans les résultats est le inputter.username, pas tous les d'autres choses. J'ai essayé plusieurs itérations d'implémenter un attribut exclude sur le gestionnaire en vain. Si je saute juste le champ entier de requête, qui fonctionne très bien, comme ceci:

dans le gestionnaire:

exclude = ('request',) 

qui se traduit par:

<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> 

Mais ces résultats ne sont pas non plus ce que je veux .

Alors, enfin, ma question:

Comment puis-je exclure les champs imbriqués à partir des résultats de gestionnaire? Est-ce même possible?

J'ai essayé différentes itérations de ce qui suit, tous qui soit ont aucun résultat, ou des résultats inattendus:

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

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

Je suppose que je comprends mal ou abusant de l'exclusion sur le terrain façon de faire dans ce contexte , donc toute l'illumination sur ce sujet est grandement appréciée.

Répondre

3

Vous pouvez obtenir le résultat souhaité en spécifiant les champs souhaités via la clause fields = du gestionnaire.

champs de modèle provenant de clés étrangères peuvent être spécifiées comme ceci:

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

Dans votre cas, ce qui suit devrait travailler (certains de vos champs laissés de côté par souci de concision):

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

Cela fonctionne vraiment. Merci pour la réponse! Plus fastidieux que ce que j'espérais (surtout quand je devrais invariablement dupliquer cela sur plusieurs gestionnaires), mais une solution est une solution! – jathanism

3

Pouvez-vous essayer d'utiliser include au lieu d'exclure? Par exemple.

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

Je ne me souviens pas si je l'ai écrit exclude être aussi polyvalent que include.

En outre, le groupe django-piston Google est l'endroit où nous discutons la plupart des choses, vous pouvez avoir plus de succès en posant cette question là.

+0

Merci pour Sonnerie, Jesper. Je vais dupe ce sur la liste de diffusion. – jathanism