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
2b59df00
Commit
2b59df00
authored
Feb 23, 2012
by
Tom Christie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
reverse takes request as a kwarg for compatibility with django's reverse
parent
8e0b9e55
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
82 additions
and
61 deletions
+82
-61
djangorestframework/compat.py
+1
-11
djangorestframework/resources.py
+10
-4
djangorestframework/reverse.py
+7
-10
djangorestframework/tests/reverse.py
+1
-1
examples/blogpost/resources.py
+6
-2
examples/mixin/urls.py
+4
-3
examples/modelresourceexample/models.py
+1
-2
examples/modelresourceexample/resources.py
+1
-0
examples/modelresourceexample/urls.py
+1
-1
examples/objectstore/views.py
+35
-16
examples/pygments_api/views.py
+7
-3
examples/resourceexample/views.py
+1
-1
examples/sandbox/views.py
+7
-7
No files found.
djangorestframework/compat.py
View file @
2b59df00
...
...
@@ -214,18 +214,15 @@ else:
REASON_NO_CSRF_COOKIE
=
"CSRF cookie not set."
REASON_BAD_TOKEN
=
"CSRF token missing or incorrect."
def
_get_failure_view
():
"""
Returns the view to be used for CSRF rejections
"""
return
get_callable
(
settings
.
CSRF_FAILURE_VIEW
)
def
_get_new_csrf_key
():
return
hashlib
.
md5
(
"
%
s
%
s"
%
(
randrange
(
0
,
_MAX_CSRF_KEY
),
settings
.
SECRET_KEY
))
.
hexdigest
()
def
get_token
(
request
):
"""
Returns the the CSRF token required for a POST form. The token is an
...
...
@@ -239,7 +236,6 @@ else:
request
.
META
[
"CSRF_COOKIE_USED"
]
=
True
return
request
.
META
.
get
(
"CSRF_COOKIE"
,
None
)
def
_sanitize_token
(
token
):
# Allow only alphanum, and ensure we return a 'str' for the sake of the post
# processing middleware.
...
...
@@ -432,6 +428,7 @@ try:
except
ImportError
:
yaml
=
None
import
unittest
try
:
import
unittest.skip
...
...
@@ -458,13 +455,6 @@ except ImportError: # python < 2.7
unittest
.
skip
=
skip
# reverse_lazy (Django 1.4 onwards)
try
:
from
django.core.urlresolvers
import
reverse_lazy
except
:
from
django.core.urlresolvers
import
reverse
from
django.utils.functional
import
lazy
reverse_lazy
=
lazy
(
reverse
,
str
)
# xml.etree.parse only throws ParseError for python >= 2.7
try
:
...
...
djangorestframework/resources.py
View file @
2b59df00
...
...
@@ -10,7 +10,8 @@ from djangorestframework.utils import as_tuple
class
BaseResource
(
Serializer
):
"""
Base class for all Resource classes, which simply defines the interface they provide.
Base class for all Resource classes, which simply defines the interface
they provide.
"""
fields
=
None
include
=
None
...
...
@@ -19,11 +20,13 @@ 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
def
validate_request
(
self
,
data
,
files
=
None
):
"""
Given the request content return the cleaned, validated content.
Typically raises a :exc:`response.ErrorResponse` with status code 400 (Bad Request) on failure.
Typically raises a :exc:`response.ErrorResponse` with status code 400
(Bad Request) on failure.
"""
return
data
...
...
@@ -37,7 +40,8 @@ class BaseResource(Serializer):
class
Resource
(
BaseResource
):
"""
A Resource determines how a python object maps to some serializable data.
Objects that a resource can act on include plain Python object instances, Django Models, and Django QuerySets.
Objects that a resource can act on include plain Python object instances,
Django Models, and Django QuerySets.
"""
# The model attribute refers to the Django Model which this Resource maps to.
...
...
@@ -355,7 +359,9 @@ class ModelResource(FormResource):
instance_attrs
[
param
]
=
attr
try
:
return
reverse
(
self
.
view_callable
[
0
],
self
.
view
.
request
,
kwargs
=
instance_attrs
)
return
reverse
(
self
.
view_callable
[
0
],
kwargs
=
instance_attrs
,
request
=
self
.
view
.
request
)
except
NoReverseMatch
:
pass
raise
_SkipField
...
...
djangorestframework/reverse.py
View file @
2b59df00
...
...
@@ -2,22 +2,19 @@
Provide reverse functions that return fully qualified URLs
"""
from
django.core.urlresolvers
import
reverse
as
django_reverse
from
django
restframework.compat
import
reverse_lazy
as
django_reverse_
lazy
from
django
.utils.functional
import
lazy
def
reverse
(
viewname
,
request
,
*
args
,
**
kwargs
):
"""
Do the same as `django.core.urlresolvers.reverse` but using
*request* to build a fully qualified
URL.
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.
"""
request
=
kwargs
.
pop
(
'request'
,
None
)
url
=
django_reverse
(
viewname
,
*
args
,
**
kwargs
)
if
request
:
return
request
.
build_absolute_uri
(
url
)
return
url
def
reverse_lazy
(
viewname
,
request
,
*
args
,
**
kwargs
):
"""
Do the same as `django.core.urlresolvers.reverse_lazy` but using
*request* to build a fully qualified URL.
"""
url
=
django_reverse_lazy
(
viewname
,
*
args
,
**
kwargs
)
return
request
.
build_absolute_uri
(
url
)
reverse_lazy
=
lazy
(
reverse
,
str
)
djangorestframework/tests/reverse.py
View file @
2b59df00
...
...
@@ -15,7 +15,7 @@ class MyView(View):
renderers
=
(
JSONRenderer
,
)
def
get
(
self
,
request
):
return
reverse
(
'myview'
,
request
)
return
reverse
(
'myview'
,
request
=
request
)
urlpatterns
=
patterns
(
''
,
url
(
r'^myview$'
,
MyView
.
as_view
(),
name
=
'myview'
),
...
...
examples/blogpost/resources.py
View file @
2b59df00
...
...
@@ -12,7 +12,9 @@ class BlogPostResource(ModelResource):
ordering
=
(
'-created'
,)
def
comments
(
self
,
instance
):
return
reverse
(
'comments'
,
request
,
kwargs
=
{
'blogpost'
:
instance
.
key
})
return
reverse
(
'comments'
,
kwargs
=
{
'blogpost'
:
instance
.
key
},
request
=
self
.
request
)
class
CommentResource
(
ModelResource
):
...
...
@@ -24,4 +26,6 @@ class CommentResource(ModelResource):
ordering
=
(
'-created'
,)
def
blogpost
(
self
,
instance
):
return
reverse
(
'blog-post'
,
request
,
kwargs
=
{
'key'
:
instance
.
blogpost
.
key
})
return
reverse
(
'blog-post'
,
kwargs
=
{
'key'
:
instance
.
blogpost
.
key
},
request
=
self
.
request
)
examples/mixin/urls.py
View file @
2b59df00
...
...
@@ -9,16 +9,17 @@ from django.conf.urls.defaults import patterns, url
class
ExampleView
(
ResponseMixin
,
View
):
"""An example view using Django 1.3's class based views.
Uses djangorestframework's RendererMixin to provide support for multiple output formats."""
Uses djangorestframework's RendererMixin to provide support for multiple
output formats."""
renderers
=
DEFAULT_RENDERERS
def
get
(
self
,
request
):
url
=
reverse
(
'mixin-view'
,
request
=
request
)
response
=
Response
(
200
,
{
'description'
:
'Some example content'
,
'url'
:
reverse
(
'mixin-view'
,
request
)
})
'url'
:
url
})
return
self
.
render
(
response
)
urlpatterns
=
patterns
(
''
,
url
(
r'^$'
,
ExampleView
.
as_view
(),
name
=
'mixin-view'
),
)
examples/modelresourceexample/models.py
View file @
2b59df00
...
...
@@ -2,6 +2,7 @@ from django.db import models
MAX_INSTANCES
=
10
class
MyModel
(
models
.
Model
):
foo
=
models
.
BooleanField
()
bar
=
models
.
IntegerField
(
help_text
=
'Must be an integer.'
)
...
...
@@ -15,5 +16,3 @@ class MyModel(models.Model):
super
(
MyModel
,
self
)
.
save
(
*
args
,
**
kwargs
)
while
MyModel
.
objects
.
all
()
.
count
()
>
MAX_INSTANCES
:
MyModel
.
objects
.
all
()
.
order_by
(
'-created'
)[
0
]
.
delete
()
examples/modelresourceexample/resources.py
View file @
2b59df00
from
djangorestframework.resources
import
ModelResource
from
modelresourceexample.models
import
MyModel
class
MyModelResource
(
ModelResource
):
model
=
MyModel
fields
=
(
'foo'
,
'bar'
,
'baz'
,
'url'
)
...
...
examples/modelresourceexample/urls.py
View file @
2b59df00
...
...
@@ -4,5 +4,5 @@ from modelresourceexample.resources import MyModelResource
urlpatterns
=
patterns
(
''
,
url
(
r'^$'
,
ListOrCreateModelView
.
as_view
(
resource
=
MyModelResource
),
name
=
'model-resource-root'
),
url
(
r'^(?P<
pk>[0-9]+)/$'
,
InstanceModelView
.
as_view
(
resource
=
MyModelResource
)
),
url
(
r'^(?P<
id>[0-9]+)/$'
,
InstanceModelView
.
as_view
(
resource
=
MyModelResource
),
name
=
'model-resource-instance'
),
)
examples/objectstore/views.py
View file @
2b59df00
...
...
@@ -28,6 +28,20 @@ def remove_oldest_files(dir, max_files):
[
os
.
remove
(
path
)
for
path
in
ctime_sorted_paths
[
max_files
:]]
def
get_filename
(
key
):
"""
Given a stored object's key returns the file's path.
"""
return
os
.
path
.
join
(
OBJECT_STORE_DIR
,
key
)
def
get_file_url
(
key
,
request
):
"""
Given a stored object's key returns the URL for the object.
"""
return
reverse
(
'stored-object'
,
kwargs
=
{
'key'
:
key
},
request
=
request
)
class
ObjectStoreRoot
(
View
):
"""
Root of the Object Store API.
...
...
@@ -38,20 +52,24 @@ class ObjectStoreRoot(View):
"""
Return a list of all the stored object URLs. (Ordered by creation time, newest first)
"""
filepaths
=
[
os
.
path
.
join
(
OBJECT_STORE_DIR
,
file
)
for
file
in
os
.
listdir
(
OBJECT_STORE_DIR
)
if
not
file
.
startswith
(
'.'
)]
filepaths
=
[
os
.
path
.
join
(
OBJECT_STORE_DIR
,
file
)
for
file
in
os
.
listdir
(
OBJECT_STORE_DIR
)
if
not
file
.
startswith
(
'.'
)]
ctime_sorted_basenames
=
[
item
[
0
]
for
item
in
sorted
([(
os
.
path
.
basename
(
path
),
os
.
path
.
getctime
(
path
))
for
path
in
filepaths
],
key
=
operator
.
itemgetter
(
1
),
reverse
=
True
)]
return
[
reverse
(
'stored-object'
,
request
,
kwargs
=
{
'key'
:
key
}
)
for
key
in
ctime_sorted_basenames
]
return
[
get_file_url
(
key
,
request
)
for
key
in
ctime_sorted_basenames
]
def
post
(
self
,
request
):
"""
Create a new stored object, with a unique key.
"""
key
=
str
(
uuid
.
uuid1
())
pathname
=
os
.
path
.
join
(
OBJECT_STORE_DIR
,
key
)
pickle
.
dump
(
self
.
CONTENT
,
open
(
pathname
,
'wb'
))
filename
=
get_filename
(
key
)
pickle
.
dump
(
self
.
CONTENT
,
open
(
filename
,
'wb'
))
remove_oldest_files
(
OBJECT_STORE_DIR
,
MAX_FILES
)
return
Response
(
status
.
HTTP_201_CREATED
,
self
.
CONTENT
,
{
'Location'
:
reverse
(
'stored-object'
,
request
,
kwargs
=
{
'key'
:
key
})})
url
=
get_file_url
(
key
,
request
)
return
Response
(
status
.
HTTP_201_CREATED
,
self
.
CONTENT
,
{
'Location'
:
url
})
class
StoredObject
(
View
):
...
...
@@ -59,29 +77,30 @@ class StoredObject(View):
Represents a stored object.
The object may be any picklable content.
"""
def
get
(
self
,
request
,
key
):
"""
Return a stored object, by unpickling the contents of a locally stored file.
Return a stored object, by unpickling the contents of a locally
stored file.
"""
pathname
=
os
.
path
.
join
(
OBJECT_STORE_DIR
,
key
)
if
not
os
.
path
.
exists
(
path
name
):
filename
=
get_filename
(
key
)
if
not
os
.
path
.
exists
(
file
name
):
return
Response
(
status
.
HTTP_404_NOT_FOUND
)
return
pickle
.
load
(
open
(
path
name
,
'rb'
))
return
pickle
.
load
(
open
(
file
name
,
'rb'
))
def
put
(
self
,
request
,
key
):
"""
Update/create a stored object, by pickling the request content to a locally stored file.
Update/create a stored object, by pickling the request content to a
locally stored file.
"""
pathname
=
os
.
path
.
join
(
OBJECT_STORE_DIR
,
key
)
pickle
.
dump
(
self
.
CONTENT
,
open
(
path
name
,
'wb'
))
filename
=
get_filename
(
key
)
pickle
.
dump
(
self
.
CONTENT
,
open
(
file
name
,
'wb'
))
return
self
.
CONTENT
def
delete
(
self
,
request
,
key
):
"""
Delete a stored object, by removing it's pickled file.
"""
pathname
=
os
.
path
.
join
(
OBJECT_STORE_DIR
,
key
)
if
not
os
.
path
.
exists
(
path
name
):
filename
=
get_filename
(
key
)
if
not
os
.
path
.
exists
(
file
name
):
return
Response
(
status
.
HTTP_404_NOT_FOUND
)
os
.
remove
(
path
name
)
os
.
remove
(
file
name
)
examples/pygments_api/views.py
View file @
2b59df00
...
...
@@ -30,9 +30,13 @@ def list_dir_sorted_by_ctime(dir):
"""
Return a list of files sorted by creation time
"""
filepaths
=
[
os
.
path
.
join
(
dir
,
file
)
for
file
in
os
.
listdir
(
dir
)
if
not
file
.
startswith
(
'.'
)]
return
[
item
[
0
]
for
item
in
sorted
(
[(
path
,
os
.
path
.
getctime
(
path
))
for
path
in
filepaths
],
key
=
operator
.
itemgetter
(
1
),
reverse
=
False
)
]
filepaths
=
[
os
.
path
.
join
(
dir
,
file
)
for
file
in
os
.
listdir
(
dir
)
if
not
file
.
startswith
(
'.'
)]
ctimes
=
[(
path
,
os
.
path
.
getctime
(
path
))
for
path
in
filepaths
]
ctimes
=
sorted
(
ctimes
,
key
=
operator
.
itemgetter
(
1
),
reverse
=
False
)
return
[
filepath
for
filepath
,
ctime
in
ctimes
]
def
remove_oldest_files
(
dir
,
max_files
):
"""
...
...
examples/resourceexample/views.py
View file @
2b59df00
...
...
@@ -15,7 +15,7 @@ class ExampleView(View):
"""
Handle GET requests, returning a list of URLs pointing to 3 other views.
"""
return
{
"Some other resources"
:
[
reverse
(
'another-example'
,
request
,
kwargs
=
{
'num'
:
num
}
)
for
num
in
range
(
3
)]}
return
{
"Some other resources"
:
[
reverse
(
'another-example'
,
kwargs
=
{
'num'
:
num
},
request
=
request
)
for
num
in
range
(
3
)]}
class
AnotherExampleView
(
View
):
...
...
examples/sandbox/views.py
View file @
2b59df00
...
...
@@ -27,11 +27,11 @@ class Sandbox(View):
Please feel free to browse, create, edit and delete the resources in these examples."""
def
get
(
self
,
request
):
return
[{
'name'
:
'Simple Resource example'
,
'url'
:
reverse
(
'example-resource'
,
request
)},
{
'name'
:
'Simple ModelResource example'
,
'url'
:
reverse
(
'model-resource-root'
,
request
)},
{
'name'
:
'Simple Mixin-only example'
,
'url'
:
reverse
(
'mixin-view'
,
request
)},
{
'name'
:
'Object store API'
,
'url'
:
reverse
(
'object-store-root'
,
request
)},
{
'name'
:
'Code highlighting API'
,
'url'
:
reverse
(
'pygments-root'
,
request
)},
{
'name'
:
'Blog posts API'
,
'url'
:
reverse
(
'blog-posts-root'
,
request
)},
{
'name'
:
'Permissions example'
,
'url'
:
reverse
(
'permissions-example'
,
request
)}
return
[{
'name'
:
'Simple Resource example'
,
'url'
:
reverse
(
'example-resource'
,
request
=
request
)},
{
'name'
:
'Simple ModelResource example'
,
'url'
:
reverse
(
'model-resource-root'
,
request
=
request
)},
{
'name'
:
'Simple Mixin-only example'
,
'url'
:
reverse
(
'mixin-view'
,
request
=
request
)},
{
'name'
:
'Object store API'
,
'url'
:
reverse
(
'object-store-root'
,
request
=
request
)},
{
'name'
:
'Code highlighting API'
,
'url'
:
reverse
(
'pygments-root'
,
request
=
request
)},
{
'name'
:
'Blog posts API'
,
'url'
:
reverse
(
'blog-posts-root'
,
request
=
request
)},
{
'name'
:
'Permissions example'
,
'url'
:
reverse
(
'permissions-example'
,
request
=
request
)}
]
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