Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
django-rest-framework
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
django-rest-framework
Commits
8756664e
Commit
8756664e
authored
May 02, 2011
by
Tom Christie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
emitters -> renderers
parent
b358fbdb
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
108 additions
and
97 deletions
+108
-97
djangorestframework/mixins.py
+89
-1
djangorestframework/modelresource.py
+9
-86
djangorestframework/renderers.py
+1
-1
djangorestframework/resource.py
+0
-2
examples/blogpost/models.py
+4
-1
examples/blogpost/views.py
+3
-4
examples/mixin/urls.py
+1
-1
examples/pygments_api/views.py
+1
-1
No files found.
djangorestframework/mixins.py
View file @
8756664e
...
@@ -6,6 +6,7 @@ from djangorestframework import status
...
@@ -6,6 +6,7 @@ from djangorestframework import status
from
django.http
import
HttpResponse
from
django.http
import
HttpResponse
from
django.http.multipartparser
import
LimitBytes
# TODO: Use LimitedStream in compat
from
django.http.multipartparser
import
LimitBytes
# TODO: Use LimitedStream in compat
from
StringIO
import
StringIO
from
StringIO
import
StringIO
from
decimal
import
Decimal
from
decimal
import
Decimal
import
re
import
re
...
@@ -233,7 +234,7 @@ class RequestMixin(object):
...
@@ -233,7 +234,7 @@ class RequestMixin(object):
@property
@property
def
default_parser
(
self
):
def
default_parser
(
self
):
"""Return the view's most pref
fe
red renderer.
"""Return the view's most pref
er
red renderer.
(This has no behavioural effect, but is may be used by documenting renderers)"""
(This has no behavioural effect, but is may be used by documenting renderers)"""
return
self
.
parsers
[
0
]
return
self
.
parsers
[
0
]
...
@@ -437,3 +438,90 @@ class AuthMixin(object):
...
@@ -437,3 +438,90 @@ class AuthMixin(object):
'You may need to login or otherwise authenticate the request.'
})
'You may need to login or otherwise authenticate the request.'
})
########## Model Mixins ##########
class
ReadModelMixin
(
object
):
"""Behaviour to read a model instance on GET requests"""
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
try
:
if
args
:
# If we have any none kwargs then assume the last represents the primrary key
instance
=
self
.
model
.
objects
.
get
(
pk
=
args
[
-
1
],
**
kwargs
)
else
:
# Otherwise assume the kwargs uniquely identify the model
instance
=
self
.
model
.
objects
.
get
(
**
kwargs
)
except
self
.
model
.
DoesNotExist
:
raise
ErrorResponse
(
status
.
HTTP_404_NOT_FOUND
)
return
instance
class
CreateModelMixin
(
object
):
"""Behaviour to create a model instance on POST requests"""
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
# translated 'related_field' kwargs into 'related_field_id'
for
related_name
in
[
field
.
name
for
field
in
self
.
model
.
_meta
.
fields
if
isinstance
(
field
,
RelatedField
)]:
if
kwargs
.
has_key
(
related_name
):
kwargs
[
related_name
+
'_id'
]
=
kwargs
[
related_name
]
del
kwargs
[
related_name
]
all_kw_args
=
dict
(
self
.
CONTENT
.
items
()
+
kwargs
.
items
())
if
args
:
instance
=
self
.
model
(
pk
=
args
[
-
1
],
**
all_kw_args
)
else
:
instance
=
self
.
model
(
**
all_kw_args
)
instance
.
save
()
headers
=
{}
if
hasattr
(
instance
,
'get_absolute_url'
):
headers
[
'Location'
]
=
instance
.
get_absolute_url
()
return
Response
(
status
.
HTTP_201_CREATED
,
instance
,
headers
)
class
UpdateModelMixin
(
object
):
"""Behaviour to update a model instance on PUT requests"""
def
put
(
self
,
request
,
*
args
,
**
kwargs
):
# 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
:
# If we have any none kwargs then assume the last represents the primrary key
instance
=
self
.
model
.
objects
.
get
(
pk
=
args
[
-
1
],
**
kwargs
)
else
:
# Otherwise assume the kwargs uniquely identify the model
instance
=
self
.
model
.
objects
.
get
(
**
kwargs
)
for
(
key
,
val
)
in
self
.
CONTENT
.
items
():
setattr
(
instance
,
key
,
val
)
except
self
.
model
.
DoesNotExist
:
instance
=
self
.
model
(
**
self
.
CONTENT
)
instance
.
save
()
instance
.
save
()
return
instance
class
DeleteModelMixin
(
object
):
"""Behaviour to delete a model instance on DELETE requests"""
def
delete
(
self
,
request
,
*
args
,
**
kwargs
):
try
:
if
args
:
# If we have any none kwargs then assume the last represents the primrary key
instance
=
self
.
model
.
objects
.
get
(
pk
=
args
[
-
1
],
**
kwargs
)
else
:
# Otherwise assume the kwargs uniquely identify the model
instance
=
self
.
model
.
objects
.
get
(
**
kwargs
)
except
self
.
model
.
DoesNotExist
:
raise
ErrorResponse
(
status
.
HTTP_404_NOT_FOUND
,
None
,
{})
instance
.
delete
()
return
class
ListModelMixin
(
object
):
"""Behaviour to list a set of model instances on GET requests"""
queryset
=
None
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
queryset
=
self
.
queryset
if
self
.
queryset
else
self
.
model
.
objects
.
all
()
return
queryset
.
filter
(
**
kwargs
)
djangorestframework/modelresource.py
View file @
8756664e
...
@@ -341,94 +341,16 @@ class ModelResource(Resource):
...
@@ -341,94 +341,16 @@ class ModelResource(Resource):
return
_any
(
data
,
self
.
fields
)
return
_any
(
data
,
self
.
fields
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
try
:
if
args
:
# If we have any none kwargs then assume the last represents the primrary key
instance
=
self
.
model
.
objects
.
get
(
pk
=
args
[
-
1
],
**
kwargs
)
else
:
# Otherwise assume the kwargs uniquely identify the model
instance
=
self
.
model
.
objects
.
get
(
**
kwargs
)
except
self
.
model
.
DoesNotExist
:
raise
ErrorResponse
(
status
.
HTTP_404_NOT_FOUND
)
return
instance
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
# TODO: test creation on a non-existing resource url
# translated related_field into related_field_id
for
related_name
in
[
field
.
name
for
field
in
self
.
model
.
_meta
.
fields
if
isinstance
(
field
,
RelatedField
)]:
if
kwargs
.
has_key
(
related_name
):
kwargs
[
related_name
+
'_id'
]
=
kwargs
[
related_name
]
del
kwargs
[
related_name
]
all_kw_args
=
dict
(
self
.
CONTENT
.
items
()
+
kwargs
.
items
())
if
args
:
instance
=
self
.
model
(
pk
=
args
[
-
1
],
**
all_kw_args
)
else
:
instance
=
self
.
model
(
**
all_kw_args
)
instance
.
save
()
headers
=
{}
if
hasattr
(
instance
,
'get_absolute_url'
):
headers
[
'Location'
]
=
instance
.
get_absolute_url
()
return
Response
(
status
.
HTTP_201_CREATED
,
instance
,
headers
)
def
put
(
self
,
request
,
*
args
,
**
kwargs
):
# 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
:
# If we have any none kwargs then assume the last represents the primrary key
instance
=
self
.
model
.
objects
.
get
(
pk
=
args
[
-
1
],
**
kwargs
)
else
:
# Otherwise assume the kwargs uniquely identify the model
instance
=
self
.
model
.
objects
.
get
(
**
kwargs
)
for
(
key
,
val
)
in
self
.
CONTENT
.
items
():
setattr
(
instance
,
key
,
val
)
except
self
.
model
.
DoesNotExist
:
instance
=
self
.
model
(
**
self
.
CONTENT
)
instance
.
save
()
instance
.
save
()
return
instance
def
delete
(
self
,
request
,
*
args
,
**
kwargs
):
try
:
if
args
:
# If we have any none kwargs then assume the last represents the primrary key
instance
=
self
.
model
.
objects
.
get
(
pk
=
args
[
-
1
],
**
kwargs
)
else
:
# Otherwise assume the kwargs uniquely identify the model
instance
=
self
.
model
.
objects
.
get
(
**
kwargs
)
except
self
.
model
.
DoesNotExist
:
raise
ErrorResponse
(
status
.
HTTP_404_NOT_FOUND
,
None
,
{})
instance
.
delete
()
class
InstanceModelResource
(
ReadModelMixin
,
UpdateModelMixin
,
DeleteModelMixin
,
ModelResource
):
return
"""A view which provides default operations for read/update/delete against a model instance."""
pass
class
ListOrCreateModelResource
(
CreateModelMixin
,
ListModelMixin
,
ModelResource
):
class
InstanceModelResource
(
ModelResource
):
http_method_names
=
[
'get'
,
'put'
,
'delete'
,
'head'
,
'options'
,
'trace'
,
'patch'
]
# Bit of a hack, these - needs fixing.
class
RootModelResource
(
ModelResource
):
"""A Resource which provides default operations for list and create."""
"""A Resource which provides default operations for list and create."""
queryset
=
None
pass
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
queryset
=
self
.
queryset
if
self
.
queryset
else
self
.
model
.
objects
.
all
()
return
queryset
.
filter
(
**
kwargs
)
http_method_names
=
[
'get'
,
'post'
,
'head'
,
'options'
,
'trace'
,
'patch'
]
class
QueryModelResource
(
ModelResource
):
"""Resource with default operations for list.
TODO: provide filter/order/num_results/paging, and a create operation to create queries."""
allowed_methods
=
(
'GET'
,)
queryset
=
None
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
queryset
=
self
.
queryset
if
self
.
queryset
else
self
.
model
.
objects
.
all
()
return
queryset
.
filer
(
**
kwargs
)
http_method_names
=
[
'get'
,
'head'
,
'options'
,
'trace'
,
'patch'
]
class
ListModelResource
(
ListModelMixin
,
ModelResource
):
"""Resource with default operations for list."""
pass
\ No newline at end of file
djangorestframework/renderers.py
View file @
8756664e
...
@@ -43,7 +43,7 @@ class BaseRenderer(object):
...
@@ -43,7 +43,7 @@ class BaseRenderer(object):
class
TemplateRenderer
(
BaseRenderer
):
class
TemplateRenderer
(
BaseRenderer
):
"""Provided for convienience.
"""Provided for convienience.
Emit
the output by simply rendering it with the given template."""
Render
the output by simply rendering it with the given template."""
media_type
=
None
media_type
=
None
template
=
None
template
=
None
...
...
djangorestframework/resource.py
View file @
8756664e
...
@@ -19,8 +19,6 @@ class Resource(RequestMixin, ResponseMixin, AuthMixin, View):
...
@@ -19,8 +19,6 @@ class Resource(RequestMixin, ResponseMixin, AuthMixin, View):
"""Handles incoming requests and maps them to REST operations.
"""Handles incoming requests and maps them to REST operations.
Performs request deserialization, response serialization, authentication and input validation."""
Performs request deserialization, response serialization, authentication and input validation."""
http_method_names
=
[
'get'
,
'post'
,
'put'
,
'delete'
,
'head'
,
'options'
,
'trace'
,
'patch'
]
# List of renderers the resource can serialize the response with, ordered by preference.
# List of renderers the resource can serialize the response with, ordered by preference.
renderers
=
(
renderers
.
JSONRenderer
,
renderers
=
(
renderers
.
JSONRenderer
,
renderers
.
DocumentingHTMLRenderer
,
renderers
.
DocumentingHTMLRenderer
,
...
...
examples/blogpost/models.py
View file @
8756664e
...
@@ -12,6 +12,8 @@ RATING_CHOICES = ((0, 'Awful'),
...
@@ -12,6 +12,8 @@ RATING_CHOICES = ((0, 'Awful'),
(
3
,
'Good'
),
(
3
,
'Good'
),
(
4
,
'Excellent'
))
(
4
,
'Excellent'
))
MAX_POSTS
=
10
class
BlogPost
(
models
.
Model
):
class
BlogPost
(
models
.
Model
):
key
=
models
.
CharField
(
primary_key
=
True
,
max_length
=
64
,
default
=
uuid_str
,
editable
=
False
)
key
=
models
.
CharField
(
primary_key
=
True
,
max_length
=
64
,
default
=
uuid_str
,
editable
=
False
)
title
=
models
.
CharField
(
max_length
=
128
)
title
=
models
.
CharField
(
max_length
=
128
)
...
@@ -38,9 +40,10 @@ class BlogPost(models.Model):
...
@@ -38,9 +40,10 @@ class BlogPost(models.Model):
def
save
(
self
,
*
args
,
**
kwargs
):
def
save
(
self
,
*
args
,
**
kwargs
):
self
.
slug
=
slugify
(
self
.
title
)
self
.
slug
=
slugify
(
self
.
title
)
super
(
self
.
__class__
,
self
)
.
save
(
*
args
,
**
kwargs
)
super
(
self
.
__class__
,
self
)
.
save
(
*
args
,
**
kwargs
)
for
obj
in
self
.
__class__
.
objects
.
order_by
(
'-pk'
)[
10
:]:
for
obj
in
self
.
__class__
.
objects
.
order_by
(
'-pk'
)[
MAX_POSTS
:]:
obj
.
delete
()
obj
.
delete
()
class
Comment
(
models
.
Model
):
class
Comment
(
models
.
Model
):
blogpost
=
models
.
ForeignKey
(
BlogPost
,
editable
=
False
,
related_name
=
'comments'
)
blogpost
=
models
.
ForeignKey
(
BlogPost
,
editable
=
False
,
related_name
=
'comments'
)
username
=
models
.
CharField
(
max_length
=
128
)
username
=
models
.
CharField
(
max_length
=
128
)
...
...
examples/blogpost/views.py
View file @
8756664e
from
djangorestframework.modelresource
import
InstanceModelResource
,
Root
ModelResource
from
djangorestframework.modelresource
import
InstanceModelResource
,
ListOrCreate
ModelResource
from
blogpost
import
models
from
blogpost
import
models
BLOG_POST_FIELDS
=
(
'created'
,
'title'
,
'slug'
,
'content'
,
'absolute_url'
,
'comment_url'
,
'comments_url'
)
BLOG_POST_FIELDS
=
(
'created'
,
'title'
,
'slug'
,
'content'
,
'absolute_url'
,
'comment_url'
,
'comments_url'
)
COMMENT_FIELDS
=
(
'username'
,
'comment'
,
'created'
,
'rating'
,
'absolute_url'
,
'blogpost_url'
)
COMMENT_FIELDS
=
(
'username'
,
'comment'
,
'created'
,
'rating'
,
'absolute_url'
,
'blogpost_url'
)
MAX_POSTS
=
10
class
BlogPosts
(
Root
ModelResource
):
class
BlogPosts
(
ListOrCreate
ModelResource
):
"""A resource with which lists all existing blog posts and creates new blog posts."""
"""A resource with which lists all existing blog posts and creates new blog posts."""
model
=
models
.
BlogPost
model
=
models
.
BlogPost
fields
=
BLOG_POST_FIELDS
fields
=
BLOG_POST_FIELDS
...
@@ -16,7 +15,7 @@ class BlogPostInstance(InstanceModelResource):
...
@@ -16,7 +15,7 @@ class BlogPostInstance(InstanceModelResource):
model
=
models
.
BlogPost
model
=
models
.
BlogPost
fields
=
BLOG_POST_FIELDS
fields
=
BLOG_POST_FIELDS
class
Comments
(
Root
ModelResource
):
class
Comments
(
ListOrCreate
ModelResource
):
"""A resource which lists all existing comments for a given blog post, and creates new blog comments for a given blog post."""
"""A resource which lists all existing comments for a given blog post, and creates new blog comments for a given blog post."""
model
=
models
.
Comment
model
=
models
.
Comment
fields
=
COMMENT_FIELDS
fields
=
COMMENT_FIELDS
...
...
examples/mixin/urls.py
View file @
8756664e
...
@@ -15,7 +15,7 @@ class ExampleView(ResponseMixin, View):
...
@@ -15,7 +15,7 @@ class ExampleView(ResponseMixin, View):
def
get
(
self
,
request
):
def
get
(
self
,
request
):
response
=
Response
(
200
,
{
'description'
:
'Some example content'
,
response
=
Response
(
200
,
{
'description'
:
'Some example content'
,
'url'
:
reverse
(
'mixin-view'
)})
'url'
:
reverse
(
'mixin-view'
)})
return
self
.
emit
(
response
)
return
self
.
render
(
response
)
urlpatterns
=
patterns
(
''
,
urlpatterns
=
patterns
(
''
,
...
...
examples/pygments_api/views.py
View file @
8756664e
...
@@ -68,7 +68,7 @@ class PygmentsRoot(Resource):
...
@@ -68,7 +68,7 @@ class PygmentsRoot(Resource):
class
PygmentsInstance
(
Resource
):
class
PygmentsInstance
(
Resource
):
"""Simply return the stored highlighted HTML file with the correct mime type.
"""Simply return the stored highlighted HTML file with the correct mime type.
This Resource only
emit
s HTML and uses a standard HTML renderer rather than the renderers.DocumentingHTMLRenderer class."""
This Resource only
render
s HTML and uses a standard HTML renderer rather than the renderers.DocumentingHTMLRenderer class."""
renderers
=
(
HTMLRenderer
,)
renderers
=
(
HTMLRenderer
,)
def
get
(
self
,
request
,
unique_id
):
def
get
(
self
,
request
,
unique_id
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment