Creating a tastypie resource for a "singleton" non-model object

django, python, rest, tastypie

Solution

You should be able to achieve this with the following. Note I haven't actually tested this, so some tweaking may be required. A more rich example can be found in the Tastypie Docs

class SettingsResource(Resource):
    value = fields.CharField(attribute='value', help_text='setting value')

    class Meta:
        resource_name = 'setting'
        fields = ['value']
        allowed_methods = ['get']

    def detail_uri_kwargs(self, bundle_or_obj):
        kwargs = {}
        return kwargs

    def get_object_list(self, request):
        return [self.obj_get()]

    def obj_get_list(self, request=None, **kwargs):
        return [self.obj_get()]

    def obj_get(self, request=None, key=None, **kwargs):
        setting = SettingObject()
        setting.value = 'whatever value'
        return setting

The SettingObject must support the getattr and setattr methods. You can use this as a template:

class SettingObject(object):
    def __init__(self, initial=None):
        self.__dict__['_data'] = {}
        if initial:
            self.update(initial)

    def __getattr__(self, name):
        return self._data.get(name, None)

    def __setattr__(self, name, value):
        self.__dict__['_data'][name] = value

    def update(self, other):
        for k in other:
            self.__setattr__(k, other[k])

    def to_dict(self):
        return self._data

Problem

I'm using tastypie and I want to create a `Resource` for a "singleton" non-model object. For the purposes of this question, let's assume what I want the URL to represent is some system settings that exist in an `ini` file. What this means is that...: - The fields I return for this URL will be custom created for this `Resource` - there is no model that contains this information. - I want a single URL that will return the data, e.g. a `GET` request on `/api/v1/settings`. - The returned data should return in a format that is similar to a details URL - i.e., it should not have `meta` and `objects` parts. It should just contain the fields from the settings. - It should not be possible to `GET` a list of such object nor is it possible to perform `POST`, `DELETE` or `PUT` (this part I know how to do, but I'm adding this here for completeness). - Optional: it should play well with `tastypie-swagger` for API exploration purposes. I got this to work, but I think my method is kind of ass-backwards, so I want to know what is the common wisdom here. What I tried so far is to override `dehydrate` and do all the work there. This requires me to override `obj_get` but leave it empty (which is kind of ugly) and also to remove the need for `id` in the details url by overriding `override_urls`. Is there a better way of doing this?

Original source