Non-PK data for URLs in tastypie
About tastypie
- Tastypie is s REST API framework for Django
More info - http://django-tastypie.readthedocs.org/en/latest/
Tastypie filtering
When using tastypie it allows to filter your data with primary key of the model.
Consider following example model(Device) and resource(DeviceResource)
models.py
https://github.com/erangaeb/dev-notes/blob/master/django/models.py
resources.py
https://github.com/erangaeb/dev-notes/blob/master/django/resources.py
This is a part of a django app that I have written to handle android push notifications via Google Could Messaging(GCM)
This app allows to send push notifications to registered devices
Model implementation is on
models.py
(Device)Users can
CREATE
(register),UPDATE
(un-register),GET
their devices via the REST APIREST API implementation is on
resources.py
(DeviceResource)This REST API allows to interact with devices via primary key of the model(identifies as id). Following some example urls that expose by REST API
api/v1/devices/ - GET all devices, POST device
api/v1/devices/1 - GET, UPDATE device with primary key '1'
- According to the model definition the
device_id
field is also an unique field(there can be only one device for given device_id)
class Device(models.Model):
device_id = models.CharField(max_length=64, unique=True)
- So what if we need to get a device with given
device_id
?. Consider following example
api/v1/devices/1b6396a7fa5ca96f - GET, UPDATE device with device id '1b6396a7fa5ca96f'
In here we need to have
device_id
instead ofid
in urlstastypie resource
override_urls
function allows to implement these kind of url filtering
override_urls
- Following is the implementation of override_urls function
In this example if request comes with
devices/<device_id>
url pattern, tastypie redirect the request todispatch_detail
function(view).Then we need to override
ModelResource.get_resource_uri
method in order to changing the stringpk
to thedevice_id
Following is the implementation of
get_resource_uri
function
- In here
api_name
andresource_name
grab fromMeta
. Then add the new key(device_id
) as a replacement forpk
kwargs = {
'resource_name': self._meta.resource_name,
'api_name': self._meta.api_name
}
if isinstance(bundle_or_obj, Bundle):
kwargs['device_id'] = bundle_or_obj.obj.device_id
else:
kwargs['device_id'] = bundle_or_obj.device_id
- Following is an example response after this filtering. Returns device with device_id 1b6396a7fa5ca96f
url
http://localhost:8000/api/v1/devices/1b6396a7fa5ca96f?format=json
response
- Please note that all these implementation are done with tastypie version 0.9.11
- Latest version of tastypie contains
prepend_urls
function instead ofoverride_urls
function
More info
http://django-tastypie.readthedocs.org/en/latest/cookbook.html#using-non-pk-data-for-your-urls
Written by eranga bandara
Related protips
2 Responses
This seems to explain what I'm looking for, but it's not clear where the code in your examples should go. e.g. Further websearching suggests override_urls
should go in the resource class, which I suppose would be a reasonable guess, but I'd rather not have to guess, and it wasn't obvious from reading this post. I found this post in a websearch, so if it follows on from something else where this is explained, that could be why. Anyhow, thanks!
Oh, yuck, the code is in images, too. This makes copying and pasting impossible. ☹