aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--djangorestframework/mixins.py12
-rw-r--r--djangorestframework/renderers.py2
-rw-r--r--djangorestframework/resources.py126
-rw-r--r--djangorestframework/serializer.py122
-rw-r--r--djangorestframework/tests/serializer.py30
-rw-r--r--djangorestframework/tests/validators.py12
-rw-r--r--docs/examples/blogpost.rst16
-rw-r--r--docs/examples/modelviews.rst9
-rw-r--r--docs/howto/alternativeframeworks.rst37
-rw-r--r--docs/index.rst3
-rw-r--r--docs/library/serializer.rst7
-rw-r--r--examples/blogpost/models.py3
-rw-r--r--examples/blogpost/urls.py31
-rw-r--r--examples/modelresourceexample/urls.py11
-rw-r--r--examples/pygments_api/views.py11
15 files changed, 195 insertions, 237 deletions
diff --git a/djangorestframework/mixins.py b/djangorestframework/mixins.py
index 75fd3646..910d06ae 100644
--- a/djangorestframework/mixins.py
+++ b/djangorestframework/mixins.py
@@ -466,7 +466,7 @@ class InstanceMixin(object):
# We do a little dance when we store the view callable...
# we need to store it wrapped in a 1-tuple, so that inspect will treat it
# as a function when we later look it up (rather than turning it into a method).
- # This makes sure our URL reversing works ok.
+ # This makes sure our URL reversing works ok.
resource.view_callable = (view,)
return view
@@ -479,6 +479,7 @@ class ReadModelMixin(object):
"""
def get(self, request, *args, **kwargs):
model = self.resource.model
+
try:
if args:
# If we have any none kwargs then assume the last represents the primrary key
@@ -498,6 +499,7 @@ class CreateModelMixin(object):
"""
def post(self, request, *args, **kwargs):
model = self.resource.model
+
# translated 'related_field' kwargs into 'related_field_id'
for related_name in [field.name for field in model._meta.fields if isinstance(field, RelatedField)]:
if kwargs.has_key(related_name):
@@ -522,6 +524,7 @@ class UpdateModelMixin(object):
"""
def put(self, request, *args, **kwargs):
model = self.resource.model
+
# TODO: update on the url of a non-existing resource url doesn't work correctly at the moment - will end up with a new url
try:
if args:
@@ -547,6 +550,7 @@ class DeleteModelMixin(object):
"""
def delete(self, request, *args, **kwargs):
model = self.resource.model
+
try:
if args:
# If we have any none kwargs then assume the last represents the primrary key
@@ -581,10 +585,12 @@ class ListModelMixin(object):
queryset = None
def get(self, request, *args, **kwargs):
- queryset = self.queryset if self.queryset else self.resource.model.objects.all()
+ model = self.resource.model
+
+ queryset = self.queryset if self.queryset else model.objects.all()
if hasattr(self, 'resource'):
- ordering = getattr(self.resource.Meta, 'ordering', None)
+ ordering = getattr(self.resource, 'ordering', None)
else:
ordering = None
diff --git a/djangorestframework/renderers.py b/djangorestframework/renderers.py
index 9834ba5e..7aa8777c 100644
--- a/djangorestframework/renderers.py
+++ b/djangorestframework/renderers.py
@@ -181,7 +181,7 @@ class DocumentingTemplateRenderer(BaseRenderer):
# Get the form instance if we have one bound to the input
form_instance = None
- if method == view.method.lower():
+ if method == getattr(view, 'method', view.request.method).lower():
form_instance = getattr(view, 'bound_form_instance', None)
if not form_instance and hasattr(view, 'get_bound_form'):
diff --git a/djangorestframework/resources.py b/djangorestframework/resources.py
index 7a4f31d5..08f9e0ae 100644
--- a/djangorestframework/resources.py
+++ b/djangorestframework/resources.py
@@ -20,12 +20,11 @@ class BaseResource(Serializer):
"""
Base class for all Resource classes, which simply defines the interface they provide.
"""
- class Meta:
- fields = None
- include = None
- exclude = None
+ fields = None
+ include = None
+ exclude = None
- def __init__(self, view, depth=None, stack=[], **kwargs):
+ def __init__(self, view=None, depth=None, stack=[], **kwargs):
super(BaseResource, self).__init__(depth, stack, **kwargs)
self.view = view
@@ -49,20 +48,19 @@ class Resource(BaseResource):
Objects that a resource can act on include plain Python object instances, Django Models, and Django QuerySets.
"""
- class Meta:
- # The model attribute refers to the Django Model which this Resource maps to.
- # (The Model's class, rather than an instance of the Model)
- model = None
-
- # By default the set of returned fields will be the set of:
- #
- # 0. All the fields on the model, excluding 'id'.
- # 1. All the properties on the model.
- # 2. The absolute_url of the model, if a get_absolute_url method exists for the model.
- #
- # If you wish to override this behaviour,
- # you should explicitly set the fields attribute on your class.
- fields = None
+ # The model attribute refers to the Django Model which this Resource maps to.
+ # (The Model's class, rather than an instance of the Model)
+ model = None
+
+ # By default the set of returned fields will be the set of:
+ #
+ # 0. All the fields on the model, excluding 'id'.
+ # 1. All the properties on the model.
+ # 2. The absolute_url of the model, if a get_absolute_url method exists for the model.
+ #
+ # If you wish to override this behaviour,
+ # you should explicitly set the fields attribute on your class.
+ fields = None
class FormResource(Resource):
@@ -74,12 +72,11 @@ class FormResource(Resource):
view, which may be used by some renderers.
"""
- class Meta:
- """
- The :class:`Form` class that should be used for request validation.
- This can be overridden by a :attr:`form` attribute on the :class:`views.View`.
- """
- form = None
+ """
+ The :class:`Form` class that should be used for request validation.
+ This can be overridden by a :attr:`form` attribute on the :class:`views.View`.
+ """
+ form = None
def validate_request(self, data, files=None):
@@ -189,7 +186,7 @@ class FormResource(Resource):
"""
# A form on the view overrides a form on the resource.
- form = getattr(self.view, 'form', None) or self.Meta.form
+ form = getattr(self.view, 'form', None) or self.form
# Use the requested method or determine the request method
if method is None and hasattr(self.view, 'request') and hasattr(self.view, 'method'):
@@ -235,44 +232,43 @@ class ModelResource(FormResource):
# Auto-register new ModelResource classes into _model_to_resource
#__metaclass__ = _RegisterModelResource
- class Meta:
- """
- The form class that should be used for request validation.
- If set to :const:`None` then the default model form validation will be used.
+ """
+ The form class that should be used for request validation.
+ If set to :const:`None` then the default model form validation will be used.
+
+ This can be overridden by a :attr:`form` attribute on the :class:`views.View`.
+ """
+ form = None
+
+ """
+ The model class which this resource maps to.
+
+ This can be overridden by a :attr:`model` attribute on the :class:`views.View`.
+ """
+ model = None
+
+ """
+ The list of fields to use on the output.
- This can be overridden by a :attr:`form` attribute on the :class:`views.View`.
- """
- form = None
+ May be any of:
- """
- The model class which this resource maps to.
+ The name of a model field.
+ The name of an attribute on the model.
+ The name of an attribute on the resource.
+ The name of a method on the model, with a signature like ``func(self)``.
+ The name of a method on the resource, with a signature like ``func(self, instance)``.
+ """
+ fields = None
- This can be overridden by a :attr:`model` attribute on the :class:`views.View`.
- """
- model = None
+ """
+ The list of fields to exclude. This is only used if :attr:`fields` is not set.
+ """
+ exclude = ('id', 'pk')
- """
- The list of fields to use on the output.
-
- May be any of:
-
- The name of a model field.
- The name of an attribute on the model.
- The name of an attribute on the resource.
- The name of a method on the model, with a signature like ``func(self)``.
- The name of a method on the resource, with a signature like ``func(self, instance)``.
- """
- fields = None
-
- """
- The list of fields to exclude. This is only used if :attr:`fields` is not set.
- """
- exclude = ('id', 'pk')
-
- """
- The list of extra fields to include. This is only used if :attr:`fields` is not set.
- """
- include = ('url',)
+ """
+ The list of extra fields to include. This is only used if :attr:`fields` is not set.
+ """
+ include = ('url',)
def __init__(self, view):
@@ -283,7 +279,7 @@ class ModelResource(FormResource):
"""
super(ModelResource, self).__init__(view)
- self.model = getattr(view, 'model', None) or self.Meta.model
+ self.model = getattr(view, 'model', None) or self.model
def validate_request(self, data, files=None):
@@ -369,7 +365,7 @@ class ModelResource(FormResource):
if isinstance(attr, models.Model):
instance_attrs[param] = attr.pk
else:
- instance_attrs[param] = attr
+ instance_attrs[param] = attr
try:
return reverse(self.view_callable[0], kwargs=instance_attrs)
@@ -399,7 +395,7 @@ class ModelResource(FormResource):
isinstance(getattr(self.model, attr, None), property)
and not attr.startswith('_'))
- if self.Meta.fields:
- return property_fields & set(as_tuple(self.Meta.fields))
+ if self.fields:
+ return property_fields & set(as_tuple(self.fields))
- return property_fields.union(set(as_tuple(self.Meta.include))) - set(as_tuple(self.Meta.exclude))
+ return property_fields.union(set(as_tuple(self.include))) - set(as_tuple(self.exclude))
diff --git a/djangorestframework/serializer.py b/djangorestframework/serializer.py
index 47c631bc..8d73d623 100644
--- a/djangorestframework/serializer.py
+++ b/djangorestframework/serializer.py
@@ -46,30 +46,14 @@ class _SkipField(Exception):
pass
-class _BuildInnerMeta(type):
+class _RegisterSerializer(type):
"""
- Some magic so that an inner Meta class gets inheriting behavior.
+ Metaclass to register serializers.
"""
def __new__(cls, name, bases, attrs):
- # Get a list of all the inner Metas, from the bases upwards.
- inner_metas = [getattr(base, 'Meta', object) for base in bases]
- inner_metas.append(attrs.get('Meta', object))
-
- # Build up the attributes on the inner Meta.
- meta_attrs = {}
- [meta_attrs.update(inner_meta.__dict__) for inner_meta in inner_metas]
-
- # Drop private attributes.
- meta_attrs = dict([ (key, val) for (key, val) in meta_attrs.items()
- if not key.startswith('_') ])
-
- # Lovely, now we can create our inner Meta class.
- attrs['Meta'] = type('Meta', (object,), meta_attrs)
-
# Build the class and register it.
- ret = super(_BuildInnerMeta, cls).__new__(cls, name, bases, attrs)
+ ret = super(_RegisterSerializer, cls).__new__(cls, name, bases, attrs)
_serializers[name] = ret
-
return ret
@@ -78,8 +62,8 @@ class Serializer(object):
Converts python objects into plain old native types suitable for
serialization. In particular it handles models and querysets.
- The output format is specified by setting a number of attributes on the
- inner `Meta` class.
+ The output format is specified by setting a number of attributes
+ on the class.
You may also override any of the serialization methods, to provide
for more flexible behavior.
@@ -87,75 +71,61 @@ class Serializer(object):
Valid output types include anything that may be directly rendered into
json, xml etc...
"""
- __metaclass__ = _BuildInnerMeta
+ __metaclass__ = _RegisterSerializer
- class Meta:
- """
- Information on how to serialize the data.
- """
-
- fields = ()
- """
- Specify the fields to be serialized on a model or dict.
- Overrides `include` and `exclude`.
- """
+ fields = ()
+ """
+ Specify the fields to be serialized on a model or dict.
+ Overrides `include` and `exclude`.
+ """
- include = ()
- """
- Fields to add to the default set to be serialized on a model/dict.
- """
+ include = ()
+ """
+ Fields to add to the default set to be serialized on a model/dict.
+ """
- exclude = ()
- """
- Fields to remove from the default set to be serialized on a model/dict.
- """
+ exclude = ()
+ """
+ Fields to remove from the default set to be serialized on a model/dict.
+ """
- rename = {}
- """
- A dict of key->name to use for the field keys.
- """
+ rename = {}
+ """
+ A dict of key->name to use for the field keys.
+ """
- related_serializer = None
- """
- The default serializer class to use for any related models.
- """
+ related_serializer = None
+ """
+ The default serializer class to use for any related models.
+ """
- depth = None
- """
- The maximum depth to serialize to, or `None`.
- """
+ depth = None
+ """
+ The maximum depth to serialize to, or `None`.
+ """
def __init__(self, depth=None, stack=[], **kwargs):
- """
- Allow `Meta` items to be set on init.
- """
- self.depth = depth
+ self.depth = depth or self.depth
self.stack = stack
-
- if self.depth is None:
- self.depth = self.Meta.depth
-
- for (key, val) in kwargs.items():
- setattr(self.Meta, key, val)
def get_fields(self, obj):
"""
Return the set of field names/keys to use for a model instance/dict.
"""
- fields = self.Meta.fields
+ fields = self.fields
- # If Meta.fields is not set, we use the default fields and modify
- # them with Meta.include and Meta.exclude
+ # If `fields` is not set, we use the default fields and modify
+ # them with `include` and `exclude`
if not fields:
default = self.get_default_fields(obj)
- include = self.Meta.include or ()
- exclude = self.Meta.exclude or ()
+ include = self.include or ()
+ exclude = self.exclude or ()
fields = set(default + list(include)) - set(exclude)
else:
- fields = _fields_to_list(self.Meta.fields)
+ fields = _fields_to_list(self.fields)
return fields
@@ -163,7 +133,7 @@ class Serializer(object):
def get_default_fields(self, obj):
"""
Return the default list of field names/keys for a model instance/dict.
- These are used if `Meta.fields` is not given.
+ These are used if `fields` is not given.
"""
if isinstance(obj, models.Model):
opts = obj._meta
@@ -173,15 +143,14 @@ class Serializer(object):
def get_related_serializer(self, key):
- info = _fields_to_dict(self.Meta.fields).get(key, None)
+ info = _fields_to_dict(self.fields).get(key, None)
# If an element in `fields` is a 2-tuple of (str, tuple)
# then the second element of the tuple is the fields to
# set on the related serializer
if isinstance(info, (list, tuple)):
class OnTheFlySerializer(Serializer):
- class Meta:
- fields = info
+ fields = info
return OnTheFlySerializer
# If an element in `fields` is a 2-tuple of (str, Serializer)
@@ -200,15 +169,15 @@ class Serializer(object):
return _serializers[info]
# Otherwise use `related_serializer` or fall back to `Serializer`
- return getattr(self.Meta, 'related_serializer') or Serializer
+ return getattr(self, 'related_serializer') or Serializer
def serialize_key(self, key):
"""
Keys serialize to their string value,
- unless they exist in the `Meta.rename` dict.
+ unless they exist in the `rename` dict.
"""
- return getattr(self.Meta.rename, key, key)
+ return getattr(self.rename, key, key)
def serialize_val(self, key, obj):
@@ -251,8 +220,7 @@ class Serializer(object):
def serialize_model(self, instance):
"""
- Given a model instance or dict, serialize it to a dict, using
- the given behavior given on Meta.
+ Given a model instance or dict, serialize it to a dict..
"""
data = {}
diff --git a/djangorestframework/tests/serializer.py b/djangorestframework/tests/serializer.py
index cf00b104..783e941e 100644
--- a/djangorestframework/tests/serializer.py
+++ b/djangorestframework/tests/serializer.py
@@ -69,12 +69,10 @@ class TestFieldNesting(TestCase):
Test tuple nesting on `fields` attr
"""
class SerializerM2(Serializer):
- class Meta:
- fields = (('field', ('field1',)),)
+ fields = (('field', ('field1',)),)
class SerializerM3(Serializer):
- class Meta:
- fields = (('field', ('field2',)),)
+ fields = (('field', ('field2',)),)
self.assertEqual(SerializerM2().serialize(self.m2), {'field': {'field1': u'foo'}})
self.assertEqual(SerializerM3().serialize(self.m3), {'field': {'field2': u'bar'}})
@@ -85,20 +83,16 @@ class TestFieldNesting(TestCase):
Test related model serialization
"""
class NestedM2(Serializer):
- class Meta:
- fields = ('field1', )
+ fields = ('field1', )
class NestedM3(Serializer):
- class Meta:
- fields = ('field2', )
+ fields = ('field2', )
class SerializerM2(Serializer):
- class Meta:
- fields = [('field', NestedM2)]
+ fields = [('field', NestedM2)]
class SerializerM3(Serializer):
- class Meta:
- fields = [('field', NestedM3)]
+ fields = [('field', NestedM3)]
self.assertEqual(SerializerM2().serialize(self.m2), {'field': {'field1': u'foo'}})
self.assertEqual(SerializerM3().serialize(self.m3), {'field': {'field2': u'bar'}})
@@ -108,20 +102,16 @@ class TestFieldNesting(TestCase):
Test related model serialization
"""
class SerializerM2(Serializer):
- class Meta:
- fields = [('field', 'NestedM2')]
+ fields = [('field', 'NestedM2')]
class SerializerM3(Serializer):
- class Meta:
- fields = [('field', 'NestedM3')]
+ fields = [('field', 'NestedM3')]
class NestedM2(Serializer):
- class Meta:
- fields = ('field1', )
+ fields = ('field1', )
class NestedM3(Serializer):
- class Meta:
- fields = ('field2', )
+ fields = ('field2', )
self.assertEqual(SerializerM2().serialize(self.m2), {'field': {'field1': u'foo'}})
self.assertEqual(SerializerM3().serialize(self.m3), {'field': {'field2': u'bar'}})
diff --git a/djangorestframework/tests/validators.py b/djangorestframework/tests/validators.py
index 45b75c4f..a1e5d2d7 100644
--- a/djangorestframework/tests/validators.py
+++ b/djangorestframework/tests/validators.py
@@ -75,8 +75,7 @@ class TestNonFieldErrors(TestCase):
return self.cleaned_data #pragma: no cover
class MockResource(FormResource):
- class Meta:
- form = MockForm
+ form = MockForm
class MockView(View):
pass
@@ -100,12 +99,10 @@ class TestFormValidation(TestCase):
qwerty = forms.CharField(required=True)
class MockFormResource(FormResource):
- class Meta:
- form = MockForm
+ form = MockForm
class MockModelResource(ModelResource):
- class Meta:
- form = MockForm
+ form = MockForm
class MockFormView(View):
resource = MockFormResource
@@ -278,8 +275,7 @@ class TestModelFormValidator(TestCase):
return 'read only'
class MockResource(ModelResource):
- class Meta:
- model = MockModel
+ model = MockModel
class MockView(View):
resource = MockResource
diff --git a/docs/examples/blogpost.rst b/docs/examples/blogpost.rst
index 36b9d982..be91913d 100644
--- a/docs/examples/blogpost.rst
+++ b/docs/examples/blogpost.rst
@@ -18,9 +18,19 @@ In this example we're working from two related models:
Creating the resources
----------------------
-Once we have some existing models there's very little we need to do to create the API.
-Firstly create a resource for each model that defines which fields we want to expose on the model.
-Secondly we map a base view and an instance view for each resource.
+We need to create two resources that we map to our two existing models, in order to describe how the models should be serialized.
+Our resource descriptions will typically go into a module called something like 'resources.py'
+
+``resources.py``
+
+.. include:: ../../examples/blogpost/resources.py
+ :literal:
+
+Creating views for our resources
+--------------------------------
+
+Once we've created the resources there's very little we need to do to create the API.
+For each resource we'll create a base view, and an instance view.
The generic views :class:`.ListOrCreateModelView` and :class:`.InstanceModelView` provide default operations for listing, creating and updating our models via the API, and also automatically provide input validation using default ModelForms for each model.
``urls.py``
diff --git a/docs/examples/modelviews.rst b/docs/examples/modelviews.rst
index 7cc78d39..c60c9f24 100644
--- a/docs/examples/modelviews.rst
+++ b/docs/examples/modelviews.rst
@@ -25,7 +25,14 @@ Here's the model we're working from in this example:
.. include:: ../../examples/modelresourceexample/models.py
:literal:
-To add an API for the model, all we need to do is create a Resource for the model, and map a couple of views to it in our urlconf.
+To add an API for the model, first we need to create a Resource for the model.
+
+``resources.py``
+
+.. include:: ../../examples/modelresourceexample/resources.py
+ :literal:
+
+Then we simply map a couple of views to the Resource in our urlconf.
``urls.py``
diff --git a/docs/howto/alternativeframeworks.rst b/docs/howto/alternativeframeworks.rst
index c6eba1dd..dc8d1ea6 100644
--- a/docs/howto/alternativeframeworks.rst
+++ b/docs/howto/alternativeframeworks.rst
@@ -1,6 +1,35 @@
-Alternative Frameworks
-======================
+Alternative frameworks & Why Django REST framework
+==================================================
-#. `django-piston <https://bitbucket.org/jespern/django-piston/wiki/Home>`_ is excellent, and has a great community behind it. This project is based on piston code in parts.
+Alternative frameworks
+----------------------
-#. `django-tasypie <https://github.com/toastdriven/django-tastypie>`_ is also well worth looking at.
+There are a number of alternative REST frameworks for Django:
+
+* `django-piston <https://bitbucket.org/jespern/django-piston/wiki/Home>`_ is very mature, and has a large community behind it. This project was originally based on piston code in parts.
+* `django-tasypie <https://github.com/toastdriven/django-tastypie>`_ is also very good, and has a very active and helpful developer community and maintainers.
+* Other interesting projects include `dagny <https://github.com/zacharyvoase/dagny>`_ and `dj-webmachine <http://benoitc.github.com/dj-webmachine/>`_
+
+
+Why use Django REST framework?
+------------------------------
+
+The big benefits of using Django REST framework come down to:
+
+1. It's based on Django's class based views, which makes it simple, modular, and future-proof.
+2. It stays as close as possible to Django idioms and language throughout.
+3. The browse-able API makes working with the APIs extremely quick and easy.
+
+
+Why was this project created?
+-----------------------------
+
+For me the browse-able API is the most important aspect of Django REST framework.
+
+I wanted to show that Web APIs could easily be made Web browse-able,
+and demonstrate how much better browse-able Web APIs are to work with.
+
+Being able to navigate and use a Web API directly in the browser is a huge win over only having command line and programmatic
+access to the API. It enables the API to be properly self-describing, and it makes it much much quicker and easier to work with.
+There's no fundamental reason why the Web APIs we're creating shouldn't be able to render to HTML as well as JSON/XML/whatever,
+and I really think that more Web API frameworks *in whatever language* ought to be taking a similar approach.
diff --git a/docs/index.rst b/docs/index.rst
index 2bd37a85..58354ae3 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -80,8 +80,7 @@ Using Django REST framework can be as simple as adding a few lines to your urlco
from myapp.models import MyModel
class MyResource(ModelResource):
- class Meta:
- model = MyModel
+ model = MyModel
urlpatterns = patterns('',
url(r'^$', ListOrCreateModelView.as_view(resource=MyResource)),
diff --git a/docs/library/serializer.rst b/docs/library/serializer.rst
index 7942c506..63dd3308 100644
--- a/docs/library/serializer.rst
+++ b/docs/library/serializer.rst
@@ -1,10 +1,5 @@
:mod:`serializer`
=================
-.. module:: serializer
-
-.. autoclass:: serializer::Serializer.Meta
- :members:
-
-.. autoclass:: serializer::Serializer
+.. automodule:: serializer
:members:
diff --git a/examples/blogpost/models.py b/examples/blogpost/models.py
index c4925a15..d77f530d 100644
--- a/examples/blogpost/models.py
+++ b/examples/blogpost/models.py
@@ -22,6 +22,9 @@ class BlogPost(models.Model):
slug = models.SlugField(editable=False, default='')
def save(self, *args, **kwargs):
+ """
+ For the purposes of the sandbox, limit the maximum number of stored models.
+ """
self.slug = slugify(self.title)
super(self.__class__, self).save(*args, **kwargs)
for obj in self.__class__.objects.order_by('-created')[MAX_POSTS:]:
diff --git a/examples/blogpost/urls.py b/examples/blogpost/urls.py
index 6fde612e..e9bd2754 100644
--- a/examples/blogpost/urls.py
+++ b/examples/blogpost/urls.py
@@ -1,38 +1,11 @@
from django.conf.urls.defaults import patterns, url
-from django.core.urlresolvers import reverse
-
from djangorestframework.views import ListOrCreateModelView, InstanceModelView
-from djangorestframework.resources import ModelResource
-
-from blogpost.models import BlogPost, Comment
-
-
-class BlogPostResource(ModelResource):
- """
- A Blog Post has a *title* and *content*, and can be associated with zero or more comments.
- """
- class Meta:
- model = BlogPost
- fields = ('created', 'title', 'slug', 'content', 'url', 'comments')
- ordering = ('-created',)
-
- def comments(self, instance):
- return reverse('comments', kwargs={'blogpost': instance.key})
-
-
-class CommentResource(ModelResource):
- """
- A Comment is associated with a given Blog Post and has a *username* and *comment*, and optionally a *rating*.
- """
- class Meta:
- model = Comment
- fields = ('username', 'comment', 'created', 'rating', 'url', 'blogpost')
- ordering = ('-created',)
+from blogpost.resources import BlogPostResource, CommentResource
urlpatterns = patterns('',
url(r'^$', ListOrCreateModelView.as_view(resource=BlogPostResource), name='blog-posts-root'),
- url(r'^(?P<key>[^/]+)/$', InstanceModelView.as_view(resource=BlogPostResource)),
+ url(r'^(?P<key>[^/]+)/$', InstanceModelView.as_view(resource=BlogPostResource), name='blog-post'),
url(r'^(?P<blogpost>[^/]+)/comments/$', ListOrCreateModelView.as_view(resource=CommentResource), name='comments'),
url(r'^(?P<blogpost>[^/]+)/comments/(?P<id>[^/]+)/$', InstanceModelView.as_view(resource=CommentResource)),
)
diff --git a/examples/modelresourceexample/urls.py b/examples/modelresourceexample/urls.py
index 86960367..b6a16542 100644
--- a/examples/modelresourceexample/urls.py
+++ b/examples/modelresourceexample/urls.py
@@ -1,15 +1,8 @@
from django.conf.urls.defaults import patterns, url
from djangorestframework.views import ListOrCreateModelView, InstanceModelView
-from djangorestframework.resources import ModelResource
-from modelresourceexample.models import MyModel
-
-class MyModelResource(ModelResource):
- class Meta:
- model = MyModel
- fields = ('foo', 'bar', 'baz', 'url')
- ordering = ('created',)
+from modelresourceexample.resources import MyModelResource
urlpatterns = patterns('',
url(r'^$', ListOrCreateModelView.as_view(resource=MyModelResource), name='model-resource-root'),
- url(r'^([0-9]+)/$', InstanceModelView.as_view(resource=MyModelResource)),
+ url(r'^(?P<pk>[0-9]+)/$', InstanceModelView.as_view(resource=MyModelResource)),
)
diff --git a/examples/pygments_api/views.py b/examples/pygments_api/views.py
index 76647107..e50029f6 100644
--- a/examples/pygments_api/views.py
+++ b/examples/pygments_api/views.py
@@ -46,19 +46,12 @@ class HTMLRenderer(BaseRenderer):
media_type = 'text/html'
-
-class PygmentsFormResource(FormResource):
- """
- """
- form = PygmentsForm
-
-
class PygmentsRoot(View):
"""
- This example demonstrates a simple RESTful Web API aound the awesome pygments library.
+ This example demonstrates a simple RESTful Web API around the awesome pygments library.
This top level resource is used to create highlighted code snippets, and to list all the existing code snippets.
"""
- resource = PygmentsFormResource
+ form = PygmentsForm
def get(self, request):
"""