I am putting the finishing touches on an API I have written for a Django app utilizing django-piston. The API is able to search by request or IP address which are Request
or IPAddress
instances respectively. Each request can have 1 or more IPAddress
associated with it.
So, for example I have an API call that will show all IPAddress
objects matching an activity status of "active", "inactive", or "all" (for either). The Request
to which each IPAddress
instance is associated is available as IPAddress.request
.
The problem I am having is that Request.inputter
is a foreign key to the User
instance of the person who provisioned the request. When my results are returned from the handler I have created for this API call, all fields from the User
instance are displayed, including password
.
This is bad; I do not want this.
So here is my handler:
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)
And here is an example of the results from /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>
All I really want in the results is the inputter.username
, not all of the other stuff. I have tried various iterations of implementing an exclude
attribute on the handler to no avail. If I just skip the entire request field, that works fine, like so:
In handler:
exclude = ('request', )
Which results in:
<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>
But these results are also not what I want.
So, finally, my question:
How can I exclude nested fields from handler results? Is it even possible?
I have tried various iterations of the following, all of which either have no result, or unintended results:
# try to exclude request.inputter
exclude = ( ('request', ('inputter', ), ) )
# try to exclude request.inputter.password
exclude = ( ('request', ('inputter', ('password', ) ) ) )
I assume that I am misunderstanding or misusing the way field exclusions are done in this context, so any enlightenment on this topic is greatly appreciated.
You can get the desired result by specifying the desired fields via the handler's fields =
clause.
Model fields coming from foreign keys can be specified like this:
('foreign_model_field', ('nested_field1', 'nested_field2'))
In your case, the following should work (some of your fields left out for brevity):
fields = ('updated', 'expires', 'created',
('request', ('incident', 'reason', ('inputter', ('username',)))))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With