Commit e15494a1 by Tom Christie

Remove InstanceMixin auto-url magicks.

parent 2b59df00
......@@ -25,14 +25,13 @@ __all__ = (
'ResponseMixin',
'AuthMixin',
'ResourceMixin',
# Reverse URL lookup behavior
'InstanceMixin',
# Model behavior mixins
'ReadModelMixin',
'CreateModelMixin',
'UpdateModelMixin',
'DeleteModelMixin',
'ListModelMixin'
'ListModelMixin',
'PaginatorMixin'
)
......@@ -444,30 +443,6 @@ class ResourceMixin(object):
else:
return None
##########
class InstanceMixin(object):
"""
`Mixin` class that is used to identify a `View` class as being the canonical identifier
for the resources it is mapped to.
"""
@classmethod
def as_view(cls, **initkwargs):
"""
Store the callable object on the resource class that has been associated with this view.
"""
view = super(InstanceMixin, cls).as_view(**initkwargs)
resource = getattr(cls(**initkwargs), 'resource', None)
if resource:
# 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.
resource.view_callable = (view,)
return view
########## Model Mixins ##########
......@@ -599,7 +574,7 @@ class CreateModelMixin(ModelMixin):
manager.through(**data).save()
headers = {}
if hasattr(instance, 'get_absolute_url'):
if hasattr(self.resource, 'url'):
headers['Location'] = self.resource(self).url(instance)
return Response(status.HTTP_201_CREATED, instance, headers)
......
from django import forms
from django.core.urlresolvers import get_urlconf, get_resolver, NoReverseMatch
from django.db import models
from djangorestframework.response import ErrorResponse
from djangorestframework.reverse import reverse
from djangorestframework.serializer import Serializer, _SkipField
from djangorestframework.serializer import Serializer
from djangorestframework.utils import as_tuple
......@@ -20,7 +17,7 @@ class BaseResource(Serializer):
def __init__(self, view=None, depth=None, stack=[], **kwargs):
super(BaseResource, self).__init__(depth, stack, **kwargs)
self.view = view
self.request = view.request
self.request = getattr(view, 'request', None)
def validate_request(self, data, files=None):
"""
......@@ -224,9 +221,6 @@ class ModelResource(FormResource):
Also provides a :meth:`get_bound_form` method which may be used by some renderers.
"""
# Auto-register new ModelResource classes into _model_to_resource
#__metaclass__ = _RegisterModelResource
form = None
"""
The form class that should be used for request validation.
......@@ -260,7 +254,7 @@ class ModelResource(FormResource):
The list of fields to exclude. This is only used if :attr:`fields` is not set.
"""
include = ('url',)
include = ()
"""
The list of extra fields to include. This is only used if :attr:`fields` is not set.
"""
......@@ -323,49 +317,6 @@ class ModelResource(FormResource):
return form()
def url(self, instance):
"""
Attempts to reverse resolve the url of the given model *instance* for this resource.
Requires a ``View`` with :class:`mixins.InstanceMixin` to have been created for this resource.
This method can be overridden if you need to set the resource url reversing explicitly.
"""
if not hasattr(self, 'view_callable'):
raise _SkipField
# dis does teh magicks...
urlconf = get_urlconf()
resolver = get_resolver(urlconf)
possibilities = resolver.reverse_dict.getlist(self.view_callable[0])
for tuple_item in possibilities:
possibility = tuple_item[0]
# pattern = tuple_item[1]
# Note: defaults = tuple_item[2] for django >= 1.3
for result, params in possibility:
#instance_attrs = dict([ (param, getattr(instance, param)) for param in params if hasattr(instance, param) ])
instance_attrs = {}
for param in params:
if not hasattr(instance, param):
continue
attr = getattr(instance, param)
if isinstance(attr, models.Model):
instance_attrs[param] = attr.pk
else:
instance_attrs[param] = attr
try:
return reverse(self.view_callable[0],
kwargs=instance_attrs,
request=self.view.request)
except NoReverseMatch:
pass
raise _SkipField
@property
def _model_fields_set(self):
"""
......
......@@ -5,7 +5,7 @@ from django.core.urlresolvers import reverse as django_reverse
from django.utils.functional import lazy
def reverse(viewname, request, *args, **kwargs):
def reverse(viewname, *args, **kwargs):
"""
Same as `django.core.urlresolvers.reverse`, but optionally takes a request
and returns a fully qualified URL, using the request to get the base URL.
......
from django.conf.urls.defaults import patterns, url
from django.test import TestCase
from django.forms import ModelForm
from django.contrib.auth.models import Group, User
from djangorestframework.resources import ModelResource
......@@ -7,18 +6,22 @@ from djangorestframework.views import ListOrCreateModelView, InstanceModelView
from djangorestframework.tests.models import CustomUser
from djangorestframework.tests.testcases import TestModelsTestCase
class GroupResource(ModelResource):
model = Group
class UserForm(ModelForm):
class Meta:
model = User
exclude = ('last_login', 'date_joined')
class UserResource(ModelResource):
model = User
form = UserForm
class CustomUserResource(ModelResource):
model = CustomUser
......
......@@ -6,7 +6,6 @@ By setting or modifying class attributes on your view, you change it's predefine
"""
import re
from django.core.urlresolvers import set_script_prefix, get_script_prefix
from django.http import HttpResponse
from django.utils.html import escape
from django.utils.safestring import mark_safe
......@@ -269,7 +268,7 @@ class ModelView(View):
resource = resources.ModelResource
class InstanceModelView(InstanceMixin, ReadModelMixin, UpdateModelMixin, DeleteModelMixin, ModelView):
class InstanceModelView(ReadModelMixin, UpdateModelMixin, DeleteModelMixin, ModelView):
"""
A view which provides default operations for read/update/delete against a model instance.
"""
......
......@@ -2,6 +2,7 @@ from django.db import models
from django.template.defaultfilters import slugify
import uuid
def uuid_str():
return str(uuid.uuid1())
......@@ -14,6 +15,7 @@ RATING_CHOICES = ((0, 'Awful'),
MAX_POSTS = 10
class BlogPost(models.Model):
key = models.CharField(primary_key=True, max_length=64, default=uuid_str, editable=False)
title = models.CharField(max_length=128)
......@@ -37,4 +39,3 @@ class Comment(models.Model):
comment = models.TextField()
rating = models.IntegerField(blank=True, null=True, choices=RATING_CHOICES, help_text='How did you rate this post?')
created = models.DateTimeField(auto_now_add=True)
......@@ -11,6 +11,11 @@ class BlogPostResource(ModelResource):
fields = ('created', 'title', 'slug', 'content', 'url', 'comments')
ordering = ('-created',)
def url(self, instance):
return reverse('blog-post',
kwargs={'key': instance.key},
request=self.request)
def comments(self, instance):
return reverse('comments',
kwargs={'blogpost': instance.key},
......
from djangorestframework.resources import ModelResource
from djangorestframework.reverse import reverse
from modelresourceexample.models import MyModel
......@@ -6,3 +7,8 @@ class MyModelResource(ModelResource):
model = MyModel
fields = ('foo', 'bar', 'baz', 'url')
ordering = ('created',)
def url(self, instance):
return reverse('model-resource-instance',
kwargs={'id': instance.id},
request=self.request)
......@@ -2,7 +2,10 @@ from django.conf.urls.defaults import patterns, url
from djangorestframework.views import ListOrCreateModelView, InstanceModelView
from modelresourceexample.resources import MyModelResource
my_model_list = ListOrCreateModelView.as_view(resource=MyModelResource)
my_model_instance = InstanceModelView.as_view(resource=MyModelResource)
urlpatterns = patterns('',
url(r'^$', ListOrCreateModelView.as_view(resource=MyModelResource), name='model-resource-root'),
url(r'^(?P<id>[0-9]+)/$', InstanceModelView.as_view(resource=MyModelResource), name='model-resource-instance'),
url(r'^$', my_model_list, name='model-resource-root'),
url(r'^(?P<id>[0-9]+)/$', my_model_instance, name='model-resource-instance'),
)
......@@ -15,7 +15,11 @@ class ExampleView(View):
"""
Handle GET requests, returning a list of URLs pointing to 3 other views.
"""
return {"Some other resources": [reverse('another-example', kwargs={'num':num}, request=request) for num in range(3)]}
resource_urls = [reverse('another-example',
kwargs={'num': num},
request=request)
for num in range(3)]
return {"Some other resources": resource_urls}
class AnotherExampleView(View):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment