Last Updated: October 18, 2020
·
2.215K
· itseranga

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 API

  • REST 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 of id in urls

  • tastypie resource override_urls function allows to implement these kind of url filtering

override_urls

  • Following is the implementation of override_urls function

Picture

  • In this example if request comes with devices/<device_id> url pattern, tastypie redirect the request to dispatch_detail function(view).

  • Then we need to override ModelResource.get_resource_uri method in order to changing the string pk to the device_id

  • Following is the implementation of get_resource_uri function

Picture

  • In here api_name and resource_name grab from Meta. Then add the new key(device_id) as a replacement for pk
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

Picture

  • Please note that all these implementation are done with tastypie version 0.9.11
  • Latest version of tastypie contains prepend_urls function instead of override_urls function

More info
http://django-tastypie.readthedocs.org/en/latest/cookbook.html#using-non-pk-data-for-your-urls

2 Responses
Add your response

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!

over 1 year ago ·

Oh, yuck, the code is in images, too. This makes copying and pasting impossible. ☹

over 1 year ago ·