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
1c78bf53
Commit
1c78bf53
authored
Sep 06, 2012
by
Tom Christie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactoring some basics
parent
d52b4c5c
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
75 additions
and
53 deletions
+75
-53
djangorestframework/authentication.py
+22
-6
djangorestframework/exceptions.py
+1
-1
djangorestframework/permissions.py
+2
-2
djangorestframework/response.py
+2
-2
djangorestframework/tests/renderers.py
+6
-6
djangorestframework/views.py
+42
-36
No files found.
djangorestframework/authentication.py
View file @
1c78bf53
...
@@ -39,13 +39,14 @@ class BaseAuthentication(object):
...
@@ -39,13 +39,14 @@ class BaseAuthentication(object):
class
BasicAuthentication
(
BaseAuthentication
):
class
BasicAuthentication
(
BaseAuthentication
):
"""
"""
Use HTTP Basic authentication.
Base class for HTTP Basic authentication.
Subclasses should implement `.authenticate_credentials()`.
"""
"""
def
authenticate
(
self
,
request
):
def
authenticate
(
self
,
request
):
"""
"""
Returns a
:obj:
`User` if a correct username and password have been supplied
Returns a `User` if a correct username and password have been supplied
using HTTP Basic authentication. Otherwise returns
:const:
`None`.
using HTTP Basic authentication. Otherwise returns `None`.
"""
"""
from
django.utils.encoding
import
smart_unicode
,
DjangoUnicodeDecodeError
from
django.utils.encoding
import
smart_unicode
,
DjangoUnicodeDecodeError
...
@@ -58,14 +59,29 @@ class BasicAuthentication(BaseAuthentication):
...
@@ -58,14 +59,29 @@ class BasicAuthentication(BaseAuthentication):
return
None
return
None
try
:
try
:
u
name
,
passw
d
=
smart_unicode
(
auth_parts
[
0
]),
smart_unicode
(
auth_parts
[
2
])
u
serid
,
passwor
d
=
smart_unicode
(
auth_parts
[
0
]),
smart_unicode
(
auth_parts
[
2
])
except
DjangoUnicodeDecodeError
:
except
DjangoUnicodeDecodeError
:
return
None
return
None
user
=
authenticate
(
username
=
uname
,
password
=
passwd
)
return
self
.
authenticate_credentials
(
userid
,
password
)
return
None
def
authenticate_credentials
(
self
,
userid
,
password
):
"""
Given the Basic authentication userid and password, authenticate
and return a user instance.
"""
raise
NotImplementedError
(
'.authenticate_credentials() must be overridden'
)
class
UserBasicAuthentication
(
BasicAuthentication
):
def
authenticate_credentials
(
self
,
userid
,
password
):
"""
Authenticate the userid and password against username and password.
"""
user
=
authenticate
(
username
=
userid
,
password
=
password
)
if
user
is
not
None
and
user
.
is_active
:
if
user
is
not
None
and
user
.
is_active
:
return
user
return
user
return
None
class
SessionAuthentication
(
BaseAuthentication
):
class
SessionAuthentication
(
BaseAuthentication
):
...
...
djangorestframework/exceptions.py
View file @
1c78bf53
...
@@ -25,7 +25,7 @@ class ParseError(APIException):
...
@@ -25,7 +25,7 @@ class ParseError(APIException):
class
PermissionDenied
(
APIException
):
class
PermissionDenied
(
APIException
):
status_code
=
status
.
HTTP_403_FORBIDDEN
status_code
=
status
.
HTTP_403_FORBIDDEN
default_detail
=
'You do not have permission to
access this resource
.'
default_detail
=
'You do not have permission to
perform this action
.'
def
__init__
(
self
,
detail
=
None
):
def
__init__
(
self
,
detail
=
None
):
self
.
detail
=
detail
or
self
.
default_detail
self
.
detail
=
detail
or
self
.
default_detail
...
...
djangorestframework/permissions.py
View file @
1c78bf53
...
@@ -52,7 +52,7 @@ class IsAdminUser(BasePermission):
...
@@ -52,7 +52,7 @@ class IsAdminUser(BasePermission):
"""
"""
def
check_permission
(
self
,
request
,
obj
=
None
):
def
check_permission
(
self
,
request
,
obj
=
None
):
if
request
.
user
and
request
.
user
.
is_staff
()
:
if
request
.
user
and
request
.
user
.
is_staff
:
return
True
return
True
return
False
return
False
...
@@ -82,7 +82,7 @@ class DjangoModelPermissions(BasePermission):
...
@@ -82,7 +82,7 @@ class DjangoModelPermissions(BasePermission):
"""
"""
# Map methods into required permission codes.
# Map methods into required permission codes.
# Override this if you need to also provide '
read
' permissions,
# Override this if you need to also provide '
view
' permissions,
# or if you want to provide custom permission codes.
# or if you want to provide custom permission codes.
perms_map
=
{
perms_map
=
{
'GET'
:
[],
'GET'
:
[],
...
...
djangorestframework/response.py
View file @
1c78bf53
...
@@ -144,9 +144,9 @@ class Response(SimpleTemplateResponse):
...
@@ -144,9 +144,9 @@ class Response(SimpleTemplateResponse):
# attempting more specific media types first
# attempting more specific media types first
# NB. The inner loop here isn't as bad as it first looks :)
# NB. The inner loop here isn't as bad as it first looks :)
# Worst case is we're looping over len(accept_list) * len(self.renderers)
# Worst case is we're looping over len(accept_list) * len(self.renderers)
for
media_type_
lis
t
in
order_by_precedence
(
accepts
):
for
media_type_
se
t
in
order_by_precedence
(
accepts
):
for
renderer
in
renderers
:
for
renderer
in
renderers
:
for
media_type
in
media_type_
lis
t
:
for
media_type
in
media_type_
se
t
:
if
renderer
.
can_handle_response
(
media_type
):
if
renderer
.
can_handle_response
(
media_type
):
return
renderer
,
media_type
return
renderer
,
media_type
...
...
djangorestframework/tests/renderers.py
View file @
1c78bf53
...
@@ -246,9 +246,9 @@ class JSONPRendererTests(TestCase):
...
@@ -246,9 +246,9 @@ class JSONPRendererTests(TestCase):
Test JSONP rendering with View JSON Renderer.
Test JSONP rendering with View JSON Renderer.
"""
"""
resp
=
self
.
client
.
get
(
'/jsonp/jsonrenderer'
,
resp
=
self
.
client
.
get
(
'/jsonp/jsonrenderer'
,
HTTP_ACCEPT
=
'application/j
son-p
'
)
HTTP_ACCEPT
=
'application/j
avascript
'
)
self
.
assertEquals
(
resp
.
status_code
,
200
)
self
.
assertEquals
(
resp
.
status_code
,
200
)
self
.
assertEquals
(
resp
[
'Content-Type'
],
'application/j
son-p
'
)
self
.
assertEquals
(
resp
[
'Content-Type'
],
'application/j
avascript
'
)
self
.
assertEquals
(
resp
.
content
,
'callback(
%
s);'
%
_flat_repr
)
self
.
assertEquals
(
resp
.
content
,
'callback(
%
s);'
%
_flat_repr
)
def
test_without_callback_without_json_renderer
(
self
):
def
test_without_callback_without_json_renderer
(
self
):
...
@@ -256,9 +256,9 @@ class JSONPRendererTests(TestCase):
...
@@ -256,9 +256,9 @@ class JSONPRendererTests(TestCase):
Test JSONP rendering without View JSON Renderer.
Test JSONP rendering without View JSON Renderer.
"""
"""
resp
=
self
.
client
.
get
(
'/jsonp/nojsonrenderer'
,
resp
=
self
.
client
.
get
(
'/jsonp/nojsonrenderer'
,
HTTP_ACCEPT
=
'application/j
son-p
'
)
HTTP_ACCEPT
=
'application/j
avascript
'
)
self
.
assertEquals
(
resp
.
status_code
,
200
)
self
.
assertEquals
(
resp
.
status_code
,
200
)
self
.
assertEquals
(
resp
[
'Content-Type'
],
'application/j
son-p
'
)
self
.
assertEquals
(
resp
[
'Content-Type'
],
'application/j
avascript
'
)
self
.
assertEquals
(
resp
.
content
,
'callback(
%
s);'
%
_flat_repr
)
self
.
assertEquals
(
resp
.
content
,
'callback(
%
s);'
%
_flat_repr
)
def
test_with_callback
(
self
):
def
test_with_callback
(
self
):
...
@@ -267,9 +267,9 @@ class JSONPRendererTests(TestCase):
...
@@ -267,9 +267,9 @@ class JSONPRendererTests(TestCase):
"""
"""
callback_func
=
'myjsonpcallback'
callback_func
=
'myjsonpcallback'
resp
=
self
.
client
.
get
(
'/jsonp/nojsonrenderer?callback='
+
callback_func
,
resp
=
self
.
client
.
get
(
'/jsonp/nojsonrenderer?callback='
+
callback_func
,
HTTP_ACCEPT
=
'application/j
son-p
'
)
HTTP_ACCEPT
=
'application/j
avascript
'
)
self
.
assertEquals
(
resp
.
status_code
,
200
)
self
.
assertEquals
(
resp
.
status_code
,
200
)
self
.
assertEquals
(
resp
[
'Content-Type'
],
'application/j
son-p
'
)
self
.
assertEquals
(
resp
[
'Content-Type'
],
'application/j
avascript
'
)
self
.
assertEquals
(
resp
.
content
,
'
%
s(
%
s);'
%
(
callback_func
,
_flat_repr
))
self
.
assertEquals
(
resp
.
content
,
'
%
s(
%
s);'
%
(
callback_func
,
_flat_repr
))
...
...
djangorestframework/views.py
View file @
1c78bf53
...
@@ -21,15 +21,6 @@ from djangorestframework.settings import api_settings
...
@@ -21,15 +21,6 @@ from djangorestframework.settings import api_settings
from
djangorestframework
import
parsers
,
authentication
,
status
,
exceptions
,
mixins
from
djangorestframework
import
parsers
,
authentication
,
status
,
exceptions
,
mixins
__all__
=
(
'View'
,
'ModelView'
,
'InstanceModelView'
,
'ListModelView'
,
'ListOrCreateModelView'
)
def
_remove_trailing_string
(
content
,
trailing
):
def
_remove_trailing_string
(
content
,
trailing
):
"""
"""
Strip trailing component `trailing` from `content` if it exists.
Strip trailing component `trailing` from `content` if it exists.
...
@@ -65,11 +56,6 @@ def _camelcase_to_spaces(content):
...
@@ -65,11 +56,6 @@ def _camelcase_to_spaces(content):
class
APIView
(
_View
):
class
APIView
(
_View
):
"""
Handles incoming requests and maps them to REST operations.
Performs request deserialization, response serialization, authentication and input validation.
"""
renderers
=
api_settings
.
DEFAULT_RENDERERS
renderers
=
api_settings
.
DEFAULT_RENDERERS
"""
"""
List of renderer classes the view can serialize the response with, ordered by preference.
List of renderer classes the view can serialize the response with, ordered by preference.
...
@@ -81,7 +67,7 @@ class APIView(_View):
...
@@ -81,7 +67,7 @@ class APIView(_View):
"""
"""
authentication
=
(
authentication
.
SessionAuthentication
,
authentication
=
(
authentication
.
SessionAuthentication
,
authentication
.
BasicAuthentication
)
authentication
.
User
BasicAuthentication
)
"""
"""
List of all authenticating methods to attempt.
List of all authenticating methods to attempt.
"""
"""
...
@@ -155,10 +141,21 @@ class APIView(_View):
...
@@ -155,10 +141,21 @@ class APIView(_View):
def
http_method_not_allowed
(
self
,
request
,
*
args
,
**
kwargs
):
def
http_method_not_allowed
(
self
,
request
,
*
args
,
**
kwargs
):
"""
"""
Called if `request.method` does not corrospond to a handler method.
Called if `request.method` does not corrospond to a handler method.
We raise an exception, which is handled by `.handle_exception()`.
"""
"""
raise
exceptions
.
MethodNotAllowed
(
request
.
method
)
raise
exceptions
.
MethodNotAllowed
(
request
.
method
)
def
permission_denied
(
self
,
request
):
"""
If request is not permitted, determine what kind of exception to raise.
"""
raise
exceptions
.
PermissionDenied
()
def
throttled
(
self
,
request
,
wait
):
"""
If request is throttled, determine what kind of exception to raise.
"""
raise
exceptions
.
Throttled
(
wait
)
@property
@property
def
_parsed_media_types
(
self
):
def
_parsed_media_types
(
self
):
"""
"""
...
@@ -208,35 +205,29 @@ class APIView(_View):
...
@@ -208,35 +205,29 @@ class APIView(_View):
def
check_permissions
(
self
,
request
,
obj
=
None
):
def
check_permissions
(
self
,
request
,
obj
=
None
):
"""
"""
Check
user permissions and either raise an ``PermissionDenied`` or return
.
Check
if request should be permitted
.
"""
"""
for
permission
in
self
.
get_permissions
():
for
permission
in
self
.
get_permissions
():
if
not
permission
.
check_permission
(
request
,
obj
):
if
not
permission
.
check_permission
(
request
,
obj
):
raise
exceptions
.
PermissionDenied
(
)
self
.
permission_denied
(
request
)
def
check_throttles
(
self
,
request
):
def
check_throttles
(
self
,
request
):
"""
"""
Check
throttles and either raise a `Throttled` exception or return
.
Check
if request should be throttled
.
"""
"""
for
throttle
in
self
.
get_throttles
():
for
throttle
in
self
.
get_throttles
():
if
not
throttle
.
check_throttle
(
request
):
if
not
throttle
.
check_throttle
(
request
):
raise
exceptions
.
Throttled
(
throttle
.
wait
())
self
.
throttled
(
request
,
throttle
.
wait
())
def
initial
(
self
,
request
,
*
args
,
**
kargs
):
def
initial
ize_request
(
self
,
request
,
*
args
,
**
kargs
):
"""
"""
This method runs prior to anything else in the view.
Returns the initial request object.
It should return the initial request object.
You may need to override this if you want to do things like set
`request.upload_handlers` before the authentication and dispatch
handling is run.
"""
"""
return
Request
(
request
,
parsers
=
self
.
parsers
,
authentication
=
self
.
authentication
)
return
Request
(
request
,
parsers
=
self
.
parsers
,
authentication
=
self
.
authentication
)
def
final
(
self
,
request
,
response
,
*
args
,
**
kargs
):
def
final
ize_response
(
self
,
request
,
response
,
*
args
,
**
kargs
):
"""
"""
This method runs after everything else in the view.
Returns the final response object.
It should return the final response object.
"""
"""
if
isinstance
(
response
,
Response
):
if
isinstance
(
response
,
Response
):
response
.
view
=
self
response
.
view
=
self
...
@@ -248,6 +239,13 @@ class APIView(_View):
...
@@ -248,6 +239,13 @@ class APIView(_View):
return
response
return
response
def
initial
(
self
,
request
,
*
args
,
**
kwargs
):
"""
Runs anything that needs to occur prior to calling the method handlers.
"""
self
.
check_permissions
(
request
)
self
.
check_throttles
(
request
)
def
handle_exception
(
self
,
exc
):
def
handle_exception
(
self
,
exc
):
"""
"""
Handle any exception that occurs, by returning an appropriate response,
Handle any exception that occurs, by returning an appropriate response,
...
@@ -270,16 +268,24 @@ class APIView(_View):
...
@@ -270,16 +268,24 @@ class APIView(_View):
# all other authentication is CSRF exempt.
# all other authentication is CSRF exempt.
@csrf_exempt
@csrf_exempt
def
dispatch
(
self
,
request
,
*
args
,
**
kwargs
):
def
dispatch
(
self
,
request
,
*
args
,
**
kwargs
):
"""
`APIView.dispatch()` is pretty much the same as Django's regular
`View.dispatch()`, except that it includes hooks to:
* Initialize the request object.
* Finalize the response object.
* Handle exceptions that occur in the handler method.
* An initial hook for code such as permission checking that should
occur prior to running the method handlers.
"""
request
=
self
.
initialize_request
(
request
,
*
args
,
**
kwargs
)
self
.
request
=
request
self
.
args
=
args
self
.
args
=
args
self
.
kwargs
=
kwargs
self
.
kwargs
=
kwargs
self
.
headers
=
self
.
default_response_headers
self
.
headers
=
self
.
default_response_headers
try
:
try
:
self
.
request
=
self
.
initial
(
request
,
*
args
,
**
kwargs
)
self
.
initial
(
request
,
*
args
,
**
kwargs
)
# Check that the request is allowed
self
.
check_permissions
(
request
)
self
.
check_throttles
(
request
)
# Get the appropriate handler method
# Get the appropriate handler method
if
request
.
method
.
lower
()
in
self
.
http_method_names
:
if
request
.
method
.
lower
()
in
self
.
http_method_names
:
...
@@ -292,7 +298,7 @@ class APIView(_View):
...
@@ -292,7 +298,7 @@ class APIView(_View):
except
Exception
as
exc
:
except
Exception
as
exc
:
response
=
self
.
handle_exception
(
exc
)
response
=
self
.
handle_exception
(
exc
)
self
.
response
=
self
.
final
(
request
,
response
,
*
args
,
**
kwargs
)
self
.
response
=
self
.
final
ize_response
(
request
,
response
,
*
args
,
**
kwargs
)
return
self
.
response
return
self
.
response
...
...
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