Skip to content

geeknam/django-nap

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

73 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

django-nap

Build Status

A light REST library for Django.

Whilst there are many existing RESTful API tools about, many of them are very complex, and [as I found] some are quite slow!

I wanted to take the solid serialising pattern from TastyPie, with the separation of roles of django-rest-framework, and include a Publisher API I developed some time ago.

Benefits

Modular:: By having the Serialiser as a separate class from the Publisher, it's simple to have different 'shapes' of data handled for different views. You can also use the Serialisers elsewhere in your code.

Simple:: If you want an API that provides every feature ever, go look at TastyPie. But if you want something simple and fast, this is your tool.

Overview

Publisher

A publisher gives you access to the resource. Firstly, it uses the url patterns as follows:

r'^object/(?P<object_id>\w+)/(?P<action>\w+)/?$'
r'^object/(?P<object_id>\w+)/?$'
r'^(?P<action>\w+)/?$'
r'^$'

Requests are mapped to 'handlers', either list or object handlers. A handler name is formed:

{list|object}_{method}_{action}

In lieu of any action, 'default' is used.

Configuration properties:

page_size
    If defined, lists will be paginated to fit this size.  Offsets will be adjusted to a page boundary.

Internal methods:

get_serialiser():
    Return a Serialiser instance to use for this request.

get_object_list():
    Return the full object list for this request.

get_object(object_id):
    Return the instance with this ID.

get_page(object_list):
    Returns the page of objects for this request.

def get_data():
    Returns the client-supplied data.

Serialiser

A serialiser defines how to convert an object to/from a JSON encodable format.

Serialisers are defined declaratively, using nap.field.Field instances

class MySerialiser(Serialiser):
    foo = fields.Field()
    bar = fields.Field(readonly=True)
    baz = fields.Field('quux')
    fred = fields.Field('some.dotted.path')

With an instance of this class, you can deflate/inflate an instance of MyClass easily:

ser = MySerialiser()
data = ser.deflate(obj)
updated_obj = ser.inflate(data, obj)

If you try to inflate without passing an object, a dummy 'object' instance will be created and have the values stored on it.

A field marked 'readonly' will not set its value on the object.

You can customise how a field is inflated by either sublcassing the Field class, or adding a deflate_FOO or inflate_FOO method.

class BSerialiser(Serialiser):

    foo = fields.Field()

    def deflate_foo(self, obj, data, publisher=None):
        return obj.get_foo()

    def inflate_foo(self, data, obj, publisher=None):
        obj.set_foo(data['foo'])

There's also a ModelSerialiser, which will introspect for fields.

class MySerialiser(ModelSerialiser):
    class Meta:
        model = MyModel

You can define extra fields on a ModelSerialiser, or override fields from the model.

About

A light REST library for Django.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 100.0%