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
21d2dcc2
Commit
21d2dcc2
authored
May 27, 2011
by
Tom Christie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow .form specified on view. Allow get_form, put_form, post_form. Add .PARAMS.
parent
9e9ae609
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
72 additions
and
53 deletions
+72
-53
djangorestframework/mixins.py
+18
-5
djangorestframework/renderers.py
+12
-7
djangorestframework/resources.py
+32
-24
djangorestframework/templates/renderer.html
+10
-12
djangorestframework/views.py
+0
-5
No files found.
djangorestframework/mixins.py
View file @
21d2dcc2
...
...
@@ -401,12 +401,23 @@ class ResourceMixin(object):
def
CONTENT
(
self
):
"""
Returns the cleaned, validated request content.
May raise an :class:`response.ErrorResponse` with status code 400 (Bad Request).
"""
if
not
hasattr
(
self
,
'_content'
):
self
.
_content
=
self
.
validate_request
(
self
.
DATA
,
self
.
FILES
)
return
self
.
_content
@property
def
PARAMS
(
self
):
"""
Returns the cleaned, validated query parameters.
May raise an :class:`response.ErrorResponse` with status code 400 (Bad Request).
"""
return
self
.
validate_request
(
self
.
request
.
GET
)
@property
def
_resource
(
self
):
if
self
.
resource
:
return
self
.
resource
(
self
)
...
...
@@ -414,12 +425,14 @@ class ResourceMixin(object):
return
ModelResource
(
self
)
elif
getattr
(
self
,
'form'
,
None
):
return
FormResource
(
self
)
elif
getattr
(
self
,
'
%
s_form'
%
self
.
method
.
lower
(),
None
):
return
FormResource
(
self
)
return
Resource
(
self
)
def
validate_request
(
self
,
data
,
files
):
def
validate_request
(
self
,
data
,
files
=
None
):
"""
Given the request *data* return the cleaned, validated content.
Typically raises
an :class:`response.ErrorResponse` with status code 400 (Bad Request) on failure.
Given the request *data*
and optional *files*,
return the cleaned, validated content.
May raise
an :class:`response.ErrorResponse` with status code 400 (Bad Request) on failure.
"""
return
self
.
_resource
.
validate_request
(
data
,
files
)
...
...
@@ -429,8 +442,8 @@ class ResourceMixin(object):
"""
return
self
.
_resource
.
filter_response
(
obj
)
def
get_bound_form
(
self
,
content
=
None
):
return
self
.
_resource
.
get_bound_form
(
content
)
def
get_bound_form
(
self
,
content
=
None
,
method
=
None
):
return
self
.
_resource
.
get_bound_form
(
content
,
method
=
method
)
...
...
djangorestframework/renderers.py
View file @
21d2dcc2
...
...
@@ -172,7 +172,7 @@ class DocumentingTemplateRenderer(BaseRenderer):
return
content
def
_get_form_instance
(
self
,
view
):
def
_get_form_instance
(
self
,
view
,
method
):
"""
Get a form, possibly bound to either the input or output data.
In the absence on of the Resource having an associated form then
...
...
@@ -180,22 +180,24 @@ class DocumentingTemplateRenderer(BaseRenderer):
"""
# Get the form instance if we have one bound to the input
form_instance
=
getattr
(
view
,
'bound_form_instance'
,
None
)
form_instance
=
None
if
method
==
view
.
method
.
lower
():
form_instance
=
getattr
(
view
,
'bound_form_instance'
,
None
)
if
not
form_instance
and
hasattr
(
view
,
'get_bound_form'
):
# Otherwise if we have a response that is valid against the form then use that
if
view
.
response
.
has_content_body
:
try
:
form_instance
=
view
.
get_bound_form
(
view
.
response
.
cleaned_content
)
form_instance
=
view
.
get_bound_form
(
view
.
response
.
cleaned_content
,
method
=
method
)
if
form_instance
and
not
form_instance
.
is_valid
():
form_instance
=
None
except
:
form_instance
=
None
# If we still don't have a form instance then try to get an unbound form
if
not
form_instance
:
try
:
form_instance
=
view
.
get_bound_form
()
form_instance
=
view
.
get_bound_form
(
method
=
method
)
except
:
pass
...
...
@@ -250,7 +252,9 @@ class DocumentingTemplateRenderer(BaseRenderer):
needed to self-document the response to this request.
"""
content
=
self
.
_get_content
(
self
.
view
,
self
.
view
.
request
,
obj
,
media_type
)
form_instance
=
self
.
_get_form_instance
(
self
.
view
)
put_form_instance
=
self
.
_get_form_instance
(
self
.
view
,
'put'
)
post_form_instance
=
self
.
_get_form_instance
(
self
.
view
,
'post'
)
if
url_resolves
(
settings
.
LOGIN_URL
)
and
url_resolves
(
settings
.
LOGOUT_URL
):
login_url
=
"
%
s?next=
%
s"
%
(
settings
.
LOGIN_URL
,
quote_plus
(
self
.
view
.
request
.
path
))
...
...
@@ -282,7 +286,8 @@ class DocumentingTemplateRenderer(BaseRenderer):
'markeddown'
:
markeddown
,
'breadcrumblist'
:
breadcrumb_list
,
'available_media_types'
:
self
.
view
.
_rendered_media_types
,
'form'
:
form_instance
,
'put_form'
:
put_form_instance
,
'post_form'
:
post_form_instance
,
'login_url'
:
login_url
,
'logout_url'
:
logout_url
,
'ACCEPT_PARAM'
:
getattr
(
self
.
view
,
'_ACCEPT_QUERY_PARAM'
,
None
),
...
...
djangorestframework/resources.py
View file @
21d2dcc2
...
...
@@ -122,7 +122,7 @@ class BaseResource(object):
def
__init__
(
self
,
view
):
self
.
view
=
view
def
validate_request
(
self
,
data
,
files
):
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.
...
...
@@ -168,22 +168,12 @@ class FormResource(Resource):
"""
The :class:`Form` class that should be used for request validation.
This can be overridden by a :attr:`form` attribute on the :class:`.View`.
This can be overridden by a :attr:`form` attribute on the :class:`
views
.View`.
"""
form
=
None
def
__init__
(
self
,
view
):
"""
Allow a :attr:`form` attributes set on the :class:`View` to override
the :attr:`form` attribute set on the :class:`Resource`.
"""
super
(
FormResource
,
self
)
.
__init__
(
view
)
if
getattr
(
view
,
'form'
,
None
):
self
.
form
=
view
.
form
def
validate_request
(
self
,
data
,
files
):
def
validate_request
(
self
,
data
,
files
=
None
):
"""
Given some content as input return some cleaned, validated content.
Raises a :exc:`response.ErrorResponse` with status code 400 (Bad Request) on failure.
...
...
@@ -285,18 +275,34 @@ class FormResource(Resource):
raise
ErrorResponse
(
400
,
detail
)
def
get_bound_form
(
self
,
data
=
None
,
files
=
None
):
def
get_bound_form
(
self
,
data
=
None
,
files
=
None
,
method
=
None
):
"""
Given some content return a Django form bound to that content.
If form validation is turned off (:attr:`form` class attribute is :const:`None`) then returns :const:`None`.
"""
if
not
self
.
form
:
# A form on the view overrides a form on the resource.
form
=
getattr
(
self
.
view
,
'form'
,
self
.
form
)
# Use the requested method or determine the request method
if
method
is
None
and
hasattr
(
self
.
view
,
'request'
)
and
hasattr
(
self
.
view
,
'method'
):
method
=
self
.
view
.
method
elif
method
is
None
and
hasattr
(
self
.
view
,
'request'
):
method
=
self
.
view
.
request
.
method
# A method form on the view or resource overrides the general case.
# Method forms are attributes like `get_form` `post_form` `put_form`.
if
method
:
form
=
getattr
(
self
,
'
%
s_form'
%
method
.
lower
(),
form
)
form
=
getattr
(
self
.
view
,
'
%
s_form'
%
method
.
lower
(),
form
)
if
not
form
:
return
None
if
data
is
not
None
:
return
self
.
form
(
data
,
files
)
return
form
(
data
,
files
)
return
self
.
form
()
return
form
()
...
...
@@ -326,14 +332,14 @@ class ModelResource(FormResource):
The form class that should be used for request validation.
If set to :const:`None` then the default model form validation will be used.
This can be overridden by a :attr:`form` attribute on the :class:`.View`.
This can be overridden by a :attr:`form` attribute on the :class:`
views
.View`.
"""
form
=
None
"""
The model class which this resource maps to.
This can be overridden by a :attr:`model` attribute on the :class:`.View`.
This can be overridden by a :attr:`model` attribute on the :class:`
views
.View`.
"""
model
=
None
...
...
@@ -372,7 +378,7 @@ class ModelResource(FormResource):
if
getattr
(
view
,
'model'
,
None
):
self
.
model
=
view
.
model
def
validate_request
(
self
,
data
,
files
):
def
validate_request
(
self
,
data
,
files
=
None
):
"""
Given some content as input return some cleaned, validated content.
Raises a :exc:`response.ErrorResponse` with status code 400 (Bad Request) on failure.
...
...
@@ -389,7 +395,7 @@ class ModelResource(FormResource):
return
self
.
_validate
(
data
,
files
,
allowed_extra_fields
=
self
.
_property_fields_set
)
def
get_bound_form
(
self
,
data
=
None
,
files
=
None
):
def
get_bound_form
(
self
,
data
=
None
,
files
=
None
,
method
=
None
):
"""
Given some content return a ``Form`` instance bound to that content.
...
...
@@ -397,9 +403,11 @@ class ModelResource(FormResource):
to create the Form, otherwise the model will be used to create a ModelForm.
"""
if
self
.
form
:
# Use explict Form
return
super
(
ModelResource
,
self
)
.
get_bound_form
(
data
,
files
)
form
=
super
(
ModelResource
,
self
)
.
get_bound_form
(
data
,
files
,
method
=
method
)
# Use an explict Form if it exists
if
form
:
return
form
elif
self
.
model
:
# Fall back to ModelForm which we create on the fly
...
...
djangorestframework/templates/renderer.html
View file @
21d2dcc2
...
...
@@ -58,19 +58,16 @@
</form>
{% endif %}
{% comment %} *** Only display the POST/PUT/DELETE forms if we have a bound form, and if method ***
*** tunneling via POST forms is enabled. ***
*** (We could display only the POST form if method tunneling is disabled, but I think ***
*** the user experience would be confusing, so we simply turn all forms off. *** {% endcomment %}
{% if METHOD_PARAM and form %}
{# Only display the POST/PUT/DELETE forms if method tunneling via POST forms is enabled. #}
{% if METHOD_PARAM %}
{% if 'POST' in view.allowed_methods %}
<form
action=
"{{ request.path }}"
method=
"post"
{%
if
form
.
is_multipart
%}
enctype=
"multipart/form-data"
{%
endif
%}
>
<form
action=
"{{ request.path }}"
method=
"post"
{%
if
post_
form
.
is_multipart
%}
enctype=
"multipart/form-data"
{%
endif
%}
>
<fieldset
class=
'module aligned'
>
<h2>
POST {{ name }}
</h2>
{% csrf_token %}
{{ form.non_field_errors }}
{% for field in form %}
{{
post_
form.non_field_errors }}
{% for field in
post_
form %}
<div
class=
'form-row'
>
{{ field.label_tag }}
{{ field }}
...
...
@@ -86,13 +83,13 @@
{% endif %}
{% if 'PUT' in view.allowed_methods %}
<form
action=
"{{ request.path }}"
method=
"post"
{%
if
form
.
is_multipart
%}
enctype=
"multipart/form-data"
{%
endif
%}
>
<form
action=
"{{ request.path }}"
method=
"post"
{%
if
put_
form
.
is_multipart
%}
enctype=
"multipart/form-data"
{%
endif
%}
>
<fieldset
class=
'module aligned'
>
<h2>
PUT {{ name }}
</h2>
<input
type=
"hidden"
name=
"{{ METHOD_PARAM }}"
value=
"PUT"
/>
{% csrf_token %}
{{ form.non_field_errors }}
{% for field in form %}
{{
put_
form.non_field_errors }}
{% for field in
put_
form %}
<div
class=
'form-row'
>
{{ field.label_tag }}
{{ field }}
...
...
@@ -119,6 +116,7 @@
</fieldset>
</form>
{% endif %}
{% endif %}
</div>
</div>
...
...
djangorestframework/views.py
View file @
21d2dcc2
...
...
@@ -64,11 +64,6 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
"""
permissions
=
(
permissions
.
FullAnonAccess
,
)
# Allow name and description for the Resource to be set explicitly,
# overiding the default classname/docstring behaviour.
# These are used for documentation in the standard html and text renderers.
name
=
None
description
=
None
@classmethod
def
as_view
(
cls
,
**
initkwargs
):
...
...
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