Commit 412b5fc2 by Tom Christie

Support for nesting resources etc...

--HG--
rename : djangorestframework/tests/resources.py => djangorestframework/tests/serializer.py
parent 323d52e7
...@@ -582,7 +582,12 @@ class ListModelMixin(object): ...@@ -582,7 +582,12 @@ class ListModelMixin(object):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
queryset = self.queryset if self.queryset else self.resource.model.objects.all() queryset = self.queryset if self.queryset else self.resource.model.objects.all()
ordering = getattr(self.resource, 'ordering', None)
if hasattr(self, 'resource'):
ordering = getattr(self.resource.Meta, 'ordering', None)
else:
ordering = None
if ordering: if ordering:
args = as_tuple(ordering) args = as_tuple(ordering)
queryset = queryset.order_by(*args) queryset = queryset.order_by(*args)
......
"""Tests for the resource module"""
from django.test import TestCase
from djangorestframework.resources import _object_to_data
from django.db import models
import datetime
import decimal
class TestObjectToData(TestCase):
"""Tests for the _object_to_data function"""
def test_decimal(self):
"""Decimals need to be converted to a string representation."""
self.assertEquals(_object_to_data(decimal.Decimal('1.5')), '1.5')
def test_function(self):
"""Functions with no arguments should be called."""
def foo():
return 1
self.assertEquals(_object_to_data(foo), 1)
def test_method(self):
"""Methods with only a ``self`` argument should be called."""
class Foo(object):
def foo(self):
return 1
self.assertEquals(_object_to_data(Foo().foo), 1)
def test_datetime(self):
"""datetime objects are left as-is."""
now = datetime.datetime.now()
self.assertEquals(_object_to_data(now), now)
def test_tuples(self):
""" Test tuple serialisation """
class M1(models.Model):
field1 = models.CharField()
field2 = models.CharField()
class M2(models.Model):
field = models.OneToOneField(M1)
class M3(models.Model):
field = models.ForeignKey(M1)
m1 = M1(field1='foo', field2='bar')
m2 = M2(field=m1)
m3 = M3(field=m1)
Resource = type('Resource', (object,), {'fields':(), 'include':(), 'exclude':()})
r = Resource()
r.fields = (('field', ('field1')),)
self.assertEqual(_object_to_data(m2, r), dict(field=dict(field1=u'foo')))
r.fields = (('field', ('field2')),)
self.assertEqual(_object_to_data(m3, r), dict(field=dict(field2=u'bar')))
"""Tests for the resource module"""
from django.test import TestCase
from djangorestframework.serializer import Serializer
from django.db import models
import datetime
import decimal
class TestObjectToData(TestCase):
"""
Tests for the Serializer class.
"""
def setUp(self):
self.serializer = Serializer()
self.serialize = self.serializer.serialize
def test_decimal(self):
"""Decimals need to be converted to a string representation."""
self.assertEquals(self.serialize(decimal.Decimal('1.5')), '1.5')
def test_function(self):
"""Functions with no arguments should be called."""
def foo():
return 1
self.assertEquals(self.serialize(foo), 1)
def test_method(self):
"""Methods with only a ``self`` argument should be called."""
class Foo(object):
def foo(self):
return 1
self.assertEquals(self.serialize(Foo().foo), 1)
def test_datetime(self):
"""
datetime objects are left as-is.
"""
now = datetime.datetime.now()
self.assertEquals(self.serialize(now), now)
class TestFieldNesting(TestCase):
"""
Test nesting the fields in the Serializer class
"""
def setUp(self):
self.serializer = Serializer()
self.serialize = self.serializer.serialize
class M1(models.Model):
field1 = models.CharField()
field2 = models.CharField()
class M2(models.Model):
field = models.OneToOneField(M1)
class M3(models.Model):
field = models.ForeignKey(M1)
self.m1 = M1(field1='foo', field2='bar')
self.m2 = M2(field=self.m1)
self.m3 = M3(field=self.m1)
def test_tuple_nesting(self):
"""
Test tuple nesting on `fields` attr
"""
class SerializerM2(Serializer):
class Meta:
fields = (('field', ('field1',)),)
class SerializerM3(Serializer):
class Meta:
fields = (('field', ('field2',)),)
self.assertEqual(SerializerM2().serialize(self.m2), {'field': {'field1': u'foo'}})
self.assertEqual(SerializerM3().serialize(self.m3), {'field': {'field2': u'bar'}})
def test_serializer_class_nesting(self):
"""
Test related model serialization
"""
class NestedM2(Serializer):
class Meta:
fields = ('field1', )
class NestedM3(Serializer):
class Meta:
fields = ('field2', )
class SerializerM2(Serializer):
class Meta:
fields = [('field', NestedM2)]
class SerializerM3(Serializer):
class Meta:
fields = [('field', NestedM3)]
self.assertEqual(SerializerM2().serialize(self.m2), {'field': {'field1': u'foo'}})
self.assertEqual(SerializerM3().serialize(self.m3), {'field': {'field2': u'bar'}})
def test_serializer_classname_nesting(self):
"""
Test related model serialization
"""
class SerializerM2(Serializer):
class Meta:
fields = [('field', 'NestedM2')]
class SerializerM3(Serializer):
class Meta:
fields = [('field', 'NestedM3')]
class NestedM2(Serializer):
class Meta:
fields = ('field1', )
class NestedM3(Serializer):
class Meta:
fields = ('field2', )
self.assertEqual(SerializerM2().serialize(self.m2), {'field': {'field1': u'foo'}})
self.assertEqual(SerializerM3().serialize(self.m3), {'field': {'field2': u'bar'}})
...@@ -75,7 +75,8 @@ class TestNonFieldErrors(TestCase): ...@@ -75,7 +75,8 @@ class TestNonFieldErrors(TestCase):
return self.cleaned_data #pragma: no cover return self.cleaned_data #pragma: no cover
class MockResource(FormResource): class MockResource(FormResource):
form = MockForm class Meta:
form = MockForm
class MockView(View): class MockView(View):
pass pass
...@@ -99,10 +100,12 @@ class TestFormValidation(TestCase): ...@@ -99,10 +100,12 @@ class TestFormValidation(TestCase):
qwerty = forms.CharField(required=True) qwerty = forms.CharField(required=True)
class MockFormResource(FormResource): class MockFormResource(FormResource):
form = MockForm class Meta:
form = MockForm
class MockModelResource(ModelResource): class MockModelResource(ModelResource):
form = MockForm class Meta:
form = MockForm
class MockFormView(View): class MockFormView(View):
resource = MockFormResource resource = MockFormResource
...@@ -275,7 +278,8 @@ class TestModelFormValidator(TestCase): ...@@ -275,7 +278,8 @@ class TestModelFormValidator(TestCase):
return 'read only' return 'read only'
class MockResource(ModelResource): class MockResource(ModelResource):
model = MockModel class Meta:
model = MockModel
class MockView(View): class MockView(View):
resource = MockResource resource = MockResource
......
...@@ -150,8 +150,8 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): ...@@ -150,8 +150,8 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
response.headers['Allow'] = ', '.join(self.allowed_methods) response.headers['Allow'] = ', '.join(self.allowed_methods)
response.headers['Vary'] = 'Authenticate, Accept' response.headers['Vary'] = 'Authenticate, Accept'
return self.render(response) return self.render(response)
class ModelView(View): class ModelView(View):
"""A RESTful view that maps to a model in the database.""" """A RESTful view that maps to a model in the database."""
......
...@@ -80,7 +80,8 @@ Using Django REST framework can be as simple as adding a few lines to your urlco ...@@ -80,7 +80,8 @@ Using Django REST framework can be as simple as adding a few lines to your urlco
from myapp.models import MyModel from myapp.models import MyModel
class MyResource(ModelResource): class MyResource(ModelResource):
model = MyModel class Meta:
model = MyModel
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^$', ListOrCreateModelView.as_view(resource=MyResource)), url(r'^$', ListOrCreateModelView.as_view(resource=MyResource)),
...@@ -134,6 +135,7 @@ Library Reference ...@@ -134,6 +135,7 @@ Library Reference
library/renderers library/renderers
library/resource library/resource
library/response library/response
library/serializer
library/status library/status
library/views library/views
......
:mod:`serializer`
=================
.. module:: serializer
.. autoclass:: serializer::Serializer.Meta
:members:
.. autoclass:: serializer::Serializer
:members:
...@@ -11,9 +11,10 @@ class BlogPostResource(ModelResource): ...@@ -11,9 +11,10 @@ class BlogPostResource(ModelResource):
""" """
A Blog Post has a *title* and *content*, and can be associated with zero or more comments. A Blog Post has a *title* and *content*, and can be associated with zero or more comments.
""" """
model = BlogPost class Meta:
fields = ('created', 'title', 'slug', 'content', 'url', 'comments') model = BlogPost
ordering = ('-created',) fields = ('created', 'title', 'slug', 'content', 'url', 'comments')
ordering = ('-created',)
def comments(self, instance): def comments(self, instance):
return reverse('comments', kwargs={'blogpost': instance.key}) return reverse('comments', kwargs={'blogpost': instance.key})
...@@ -23,9 +24,10 @@ class CommentResource(ModelResource): ...@@ -23,9 +24,10 @@ class CommentResource(ModelResource):
""" """
A Comment is associated with a given Blog Post and has a *username* and *comment*, and optionally a *rating*. A Comment is associated with a given Blog Post and has a *username* and *comment*, and optionally a *rating*.
""" """
model = Comment class Meta:
fields = ('username', 'comment', 'created', 'rating', 'url', 'blogpost') model = Comment
ordering = ('-created',) fields = ('username', 'comment', 'created', 'rating', 'url', 'blogpost')
ordering = ('-created',)
urlpatterns = patterns('', urlpatterns = patterns('',
......
...@@ -4,9 +4,10 @@ from djangorestframework.resources import ModelResource ...@@ -4,9 +4,10 @@ from djangorestframework.resources import ModelResource
from modelresourceexample.models import MyModel from modelresourceexample.models import MyModel
class MyModelResource(ModelResource): class MyModelResource(ModelResource):
model = MyModel class Meta:
fields = ('foo', 'bar', 'baz', 'url') model = MyModel
ordering = ('created',) fields = ('foo', 'bar', 'baz', 'url')
ordering = ('created',)
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^$', ListOrCreateModelView.as_view(resource=MyModelResource), name='model-resource-root'), url(r'^$', ListOrCreateModelView.as_view(resource=MyModelResource), name='model-resource-root'),
......
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