Django Tastypie: Tips, Tricks, and Troubleshooting

Tastypie is one of the most popular REST API frameworks for Django, and surprisingly easy to get up and running if you’re already working with Django’s Models. It can, however, be a bit difficult to debug, and produce some cryptic error messages. Here are a couple of tasks I’ve had to figure out while working with this framework, tips for troubleshooting, and some general reflections.

Table of Contents

Adding Fields to a Resource

Mapping Attributes of an Object through a Reverse Relationship

Filtering via Through Relationships

Self-Referential Resources

Adding Fields to a Resource

It seems simple enough – and it is – but there are really a number of ways to do it, so you have to decide which is most appropriate for your use case.

Here, we work on the object referenced after the underscore in the function name (e.g. function dehydrate_FOO operates on the FOO field, accessible within the function as bundle.obj). Once you’ve updated it in some way, Tastypie will automatically update bundle.data['FOO'] for you.

This makes sense if you need to add a new field, which is based on the value of several other fields, or none of the other fields at all. In the example above, the string ‘some data’ is not derived from any other field, so it makes sense to put it in the dehydrate function.

3. Additional methods

There are a couple different strategies floating around for adding fields manually to a Tastypie resource. Here are some resources you may find helpful, if you have

This occurs because you are trying to assign a new field to bundle rather than to bundle.data. Make sure that when you are adding or removing fields from the bundle, particularly when implementing resource-wide dehydrate, you are operating on its data dictionary.

As you can see, the goal is to end up with a dictionary of related content titles, with the short_code of the language as their key. We’ll achieve this by grabbing the content, filtering by the grammar relationship, and the ultimately mapping the full Content object into a short and sweet dictionary entry.

The Django Models
For good measure, here are the relevant Django models.

The code itself should be rather self explanatory if you are already comfortable with map/reduce. We’re simply applying the function build_title to each item in the Content.objects list, which we pre-filter based on whether its grammar reference is the one we’re currently working on. Lastly, we pass in {} as the initial value of our dictionary. Each language becomes a key in the dictionary, and each content title becomes a value.

Filtering via Through Relationships

One thing which Tastypie doesn’t seem to support nicely out of the box is including the values of the through relationship to a model. Consider the following use-case:

You have a Task model.

You want to order these tasks using another model, TaskSequence.

You relate a Task to a TaskSequence with metadata (through a ‘through’ relationship, in a model named TaskContext, which includes information about the order of the tasks.

If you just ask Tastypie for the TaskSequence (which is related to another Resource over a simple foreign key relationship, in our case, the same GrammarResource as above), you might end up with something like this:

Take a look at the Tastypie resources for each of these three components (Task, TaskSequence, TaskContext). The most interesting code occurs in the TaskSequenceResource, where we filter on tasks related to the object in question – similarly to the example above.

Self-Referential Resources

Sometimes it makes perfect sense to have Models that refer to themselves. For example, may have a model Person, and this model may have a list of Relatives (which are also of type Person).

The difficulty comes in when each of these Person models also has a list of Relatives. There are a couple of ways to deal with this without ending up with the following error:

Maximum recursion depth exceeded

1. Make the relationship asymmetrical in the Model (and do not set full=True)
In our example, this would mean that Person A can be related to Person B (e.g. in Person A’s list of relatives) without Person B being related to Person A.

This makes it pretty easy for Tastypie to deal with, so long as you do not need the full resources in the Person list view.

This is rather straightforward. This way, the relatives will never try to flesh themselves out into detail forms when you’re viewing the Person resource as a list. However, this precludes you from seeing this same information in the detail view.

3. Create a ‘shallow’ version of the resource
But, if you need full=True on your list view, you’re kind of out of luck. The easiest solution to prevent exceeding the maximum recursion depth is to create two resources. Consider: