toastdriven/django-tastypie — pull request #302 by glencoates (2011-11-24 15:25:24+00:00)
Title: Bugfix for models with a primary key that has a default

Hi Daniel and the tastypie team,

Firstly, thanks for a great framework. Has saved a lot of time in providing a RESTful API for our app.

I put in a bugfix yesterday for tastypie's handling of models with a PK that has a default. In a couple places in the current source, you have code that reads something like:

if not bundle.obj or not bundle.obj.pk:

... which I assume is supposed to mean "if there is no object or the object has never been saved to the database". The current implementation of `Resource.build_bundle()` is:

def build_bundle(self, obj=None, data=None, request=None):
"""
Given either an object, a data dictionary or both, builds a ``Bundle``
for use throughout the ``dehydrate/hydrate`` cycle.

If no object is provided, an empty object from
``Resource._meta.object_class`` is created so that attempts to access
``bundle.obj`` do not fail.
"""
if obj is None:
obj = self._meta.object_class()

return Bundle(obj=obj, data=data, request=request)

If no obj is provided, it creates an instance of the model with all default values, assuming that the pk will be null (i.e. assuming that the model has an AutoField as the pk). This doesn't work if you have a model with a primary key field that has a default (e.g. a custom UUID field or similar).

In this patch, I've added an extra field to Bundle called `obj_is_new` which is always False except when build_bundle() creates the blank object. This allows the aforementioned checks to become:

if not bundle.obj or bundle.obj_is_new:

... which now works regardless of what kind of PK the model has.