diff options
| -rw-r--r-- | djangorestframework/mixins.py | 12 | ||||
| -rw-r--r-- | djangorestframework/renderers.py | 2 | ||||
| -rw-r--r-- | djangorestframework/resources.py | 126 | ||||
| -rw-r--r-- | djangorestframework/serializer.py | 122 | ||||
| -rw-r--r-- | djangorestframework/tests/serializer.py | 30 | ||||
| -rw-r--r-- | djangorestframework/tests/validators.py | 12 | ||||
| -rw-r--r-- | docs/examples/blogpost.rst | 16 | ||||
| -rw-r--r-- | docs/examples/modelviews.rst | 9 | ||||
| -rw-r--r-- | docs/howto/alternativeframeworks.rst | 37 | ||||
| -rw-r--r-- | docs/index.rst | 3 | ||||
| -rw-r--r-- | docs/library/serializer.rst | 7 | ||||
| -rw-r--r-- | examples/blogpost/models.py | 3 | ||||
| -rw-r--r-- | examples/blogpost/urls.py | 31 | ||||
| -rw-r--r-- | examples/modelresourceexample/urls.py | 11 | ||||
| -rw-r--r-- | examples/pygments_api/views.py | 11 | 
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):          """  | 
