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
764fbe33
Commit
764fbe33
authored
Jan 13, 2011
by
Tom Christie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Various cleanup
parent
5557dfb5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
96 additions
and
65 deletions
+96
-65
src/rest/emitters.py
+0
-9
src/rest/resource.py
+64
-34
src/rest/templates/emitter.html
+11
-10
src/rest/templates/emitter.txt
+5
-2
src/testapp/views.py
+16
-10
No files found.
src/rest/emitters.py
View file @
764fbe33
from
django.template
import
RequestContext
,
loader
from
django.template
import
RequestContext
,
loader
from
django.core.handlers.wsgi
import
STATUS_CODE_TEXT
import
json
import
json
from
utils
import
dict2xml
from
utils
import
dict2xml
...
@@ -22,14 +21,6 @@ class TemplatedEmitter(BaseEmitter):
...
@@ -22,14 +21,6 @@ class TemplatedEmitter(BaseEmitter):
template
=
loader
.
get_template
(
self
.
template
)
template
=
loader
.
get_template
(
self
.
template
)
context
=
RequestContext
(
self
.
resource
.
request
,
{
context
=
RequestContext
(
self
.
resource
.
request
,
{
'content'
:
content
,
'content'
:
content
,
'status'
:
self
.
resource
.
resp_status
,
'reason'
:
STATUS_CODE_TEXT
.
get
(
self
.
resource
.
resp_status
,
''
),
'headers'
:
self
.
resource
.
resp_headers
,
'resource_name'
:
self
.
resource
.
__class__
.
__name__
,
'resource_doc'
:
self
.
resource
.
__doc__
,
'create_form'
:
self
.
resource
.
form
,
'update_form'
:
self
.
resource
.
form
,
'request'
:
self
.
resource
.
request
,
'resource'
:
self
.
resource
,
'resource'
:
self
.
resource
,
})
})
...
...
src/rest/resource.py
View file @
764fbe33
from
django.http
import
HttpResponse
from
django.http
import
HttpResponse
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
from
django.core.handlers.wsgi
import
STATUS_CODE_TEXT
from
rest
import
emitters
,
parsers
from
rest
import
emitters
,
parsers
from
decimal
import
Decimal
from
decimal
import
Decimal
import
re
#
#
STATUS_400_BAD_REQUEST
=
400
STATUS_400_BAD_REQUEST
=
400
...
@@ -22,6 +24,10 @@ class ResourceException(Exception):
...
@@ -22,6 +24,10 @@ class ResourceException(Exception):
class
Resource
(
object
):
class
Resource
(
object
):
# List of RESTful operations which may be performed on this resource.
# List of RESTful operations which may be performed on this resource.
allowed_operations
=
(
'read'
,)
allowed_operations
=
(
'read'
,)
anon_allowed_operations
=
()
# Optional form for input validation and presentation of HTML formatted responses.
form
=
None
# List of content-types the resource can respond with, ordered by preference
# List of content-types the resource can respond with, ordered by preference
emitters
=
(
(
'application/json'
,
emitters
.
JSONEmitter
),
emitters
=
(
(
'application/json'
,
emitters
.
JSONEmitter
),
...
@@ -36,9 +42,6 @@ class Resource(object):
...
@@ -36,9 +42,6 @@ class Resource(object):
'application/x-www-form-urlencoded'
:
parsers
.
FormParser
,
'application/x-www-form-urlencoded'
:
parsers
.
FormParser
,
'multipart/form-data'
:
parsers
.
FormParser
}
'multipart/form-data'
:
parsers
.
FormParser
}
# Optional form for input validation and presentation of HTML formatted responses.
form
=
None
# Map standard HTTP methods to RESTful operations
# Map standard HTTP methods to RESTful operations
CALLMAP
=
{
'GET'
:
'read'
,
'POST'
:
'create'
,
CALLMAP
=
{
'GET'
:
'read'
,
'POST'
:
'create'
,
'PUT'
:
'update'
,
'DELETE'
:
'delete'
}
'PUT'
:
'update'
,
'DELETE'
:
'delete'
}
...
@@ -57,20 +60,34 @@ class Resource(object):
...
@@ -57,20 +60,34 @@ class Resource(object):
"""Make the class callable so it can be used as a Django view."""
"""Make the class callable so it can be used as a Django view."""
self
=
object
.
__new__
(
cls
)
self
=
object
.
__new__
(
cls
)
self
.
__init__
()
self
.
__init__
()
self
.
request
=
request
try
:
return
self
.
_handle_request
(
request
,
*
args
,
**
kwargs
)
return
self
.
_handle_request
(
request
,
*
args
,
**
kwargs
)
except
:
import
traceback
traceback
.
print_exc
()
raise
def
__init__
(
self
):
def
__init__
(
self
):
pass
pass
def
name
(
self
):
"""Provide a name for the resource.
By default this is the class name, with 'CamelCaseNames' converted to 'Camel Case Names',
although this behaviour may be overridden."""
class_name
=
self
.
__class__
.
__name__
return
re
.
sub
(
'(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))'
,
'
\\
1'
,
class_name
)
.
strip
()
def
description
(
self
):
"""Provide a description for the resource.
By default this is the class's docstring,
although this behaviour may be overridden."""
return
"
%
s"
%
self
.
__doc__
def
resp_status_text
(
self
):
"""Return reason text corrosponding to our HTTP response status code.
Provided for convienience."""
return
STATUS_CODE_TEXT
.
get
(
self
.
resp_status
,
''
)
def
reverse
(
self
,
view
,
*
args
,
**
kwargs
):
def
reverse
(
self
,
view
,
*
args
,
**
kwargs
):
"""Return a fully qualified URI for a given view or resource, using the current request as the base URI.
"""Return a fully qualified URI for a given view or resource, using the current request as the base URI.
TODO: Add SITEMAP option.
TODO: Add SITEMAP option.
...
@@ -125,8 +142,14 @@ class Resource(object):
...
@@ -125,8 +142,14 @@ class Resource(object):
return
method
return
method
def
authenticate
(
self
):
"""..."""
# user = ...
# if anon_user and not anon_allowed_operations raise PermissionDenied
# return
def
check_method_allowed
(
self
,
method
):
def
check_method_allowed
(
self
,
method
):
"""Ensure the request method is acceptable fo
t
this resource."""
"""Ensure the request method is acceptable fo
r
this resource."""
if
not
method
in
self
.
CALLMAP
.
keys
():
if
not
method
in
self
.
CALLMAP
.
keys
():
raise
ResourceException
(
STATUS_501_NOT_IMPLEMENTED
,
raise
ResourceException
(
STATUS_501_NOT_IMPLEMENTED
,
{
'detail'
:
'Unknown or unsupported method
\'
%
s
\'
'
%
method
})
{
'detail'
:
'Unknown or unsupported method
\'
%
s
\'
'
%
method
})
...
@@ -137,13 +160,12 @@ class Resource(object):
...
@@ -137,13 +160,12 @@ class Resource(object):
def
determine
_form
(
self
,
data
=
None
,
is_response
=
False
):
def
get_bound
_form
(
self
,
data
=
None
,
is_response
=
False
):
"""Optionally return a Django Form instance, which may be used for validation
"""Optionally return a Django Form instance, which may be used for validation
and/or rendered by an HTML/XHTML emitter.
and/or rendered by an HTML/XHTML emitter.
If data is not None the form will be bound to data. is_response indicates if data should be
If data is not None the form will be bound to data. is_response indicates if data should be
treated as the input data (bind to client input) or the response data (bind to an existing object).
treated as the input data (bind to client input) or the response data (bind to an existing object)."""
"""
if
self
.
form
:
if
self
.
form
:
if
data
:
if
data
:
return
self
.
form
(
data
)
return
self
.
form
(
data
)
...
@@ -156,15 +178,25 @@ class Resource(object):
...
@@ -156,15 +178,25 @@ class Resource(object):
"""Perform any resource-specific data deserialization and/or validation
"""Perform any resource-specific data deserialization and/or validation
after the initial HTTP content-type deserialization has taken place.
after the initial HTTP content-type deserialization has taken place.
Returns a tuple containing the cleaned up data, and optionally a form bound to that data.
By default this uses form validation to filter the basic input into the required types."""
By default this uses form validation to filter the basic input into the required types."""
if
self
.
form
is
None
:
if
self
.
form
is
None
:
return
data
return
(
data
,
None
)
form_instance
=
self
.
get_bound_form
(
data
)
if
not
form_instance
.
is_valid
():
if
not
form_instance
.
errors
:
details
=
'No content was supplied'
else
:
details
=
dict
((
key
,
map
(
unicode
,
val
))
for
(
key
,
val
)
in
form_instance
.
errors
.
iteritems
())
if
form_instance
.
non_field_errors
():
details
[
'_extra'
]
=
self
.
form
.
non_field_errors
()
if
not
self
.
form
.
is_valid
():
details
=
dict
((
key
,
map
(
unicode
,
val
))
for
(
key
,
val
)
in
self
.
form
.
errors
.
iteritems
())
raise
ResourceException
(
STATUS_400_BAD_REQUEST
,
{
'detail'
:
details
})
raise
ResourceException
(
STATUS_400_BAD_REQUEST
,
{
'detail'
:
details
})
return
self
.
form
.
cleaned_data
return
(
form_instance
.
cleaned_data
,
form_instance
)
def
cleanup_response
(
self
,
data
):
def
cleanup_response
(
self
,
data
):
...
@@ -188,7 +220,7 @@ class Resource(object):
...
@@ -188,7 +220,7 @@ class Resource(object):
return
self
.
parsers
[
content_type
]
return
self
.
parsers
[
content_type
]
except
KeyError
:
except
KeyError
:
raise
ResourceException
(
STATUS_415_UNSUPPORTED_MEDIA_TYPE
,
raise
ResourceException
(
STATUS_415_UNSUPPORTED_MEDIA_TYPE
,
{
'detail'
:
'Unsupported
content
type
\'
%
s
\'
'
%
content_type
})
{
'detail'
:
'Unsupported
media
type
\'
%
s
\'
'
%
content_type
})
def
determine_emitter
(
self
,
request
):
def
determine_emitter
(
self
,
request
):
...
@@ -253,13 +285,13 @@ class Resource(object):
...
@@ -253,13 +285,13 @@ class Resource(object):
5. serialize response data into response content, using standard HTTP content negotiation
5. serialize response data into response content, using standard HTTP content negotiation
"""
"""
emitter
=
None
emitter
=
None
method
=
self
.
determine_method
(
request
)
# We make these attributes to allow for a certain amount of munging,
# We make these attributes to allow for a certain amount of munging,
# eg The HTML emitter needs to render this information
# eg The HTML emitter needs to render this information
self
.
method
=
self
.
determine_method
(
request
)
self
.
request
=
request
self
.
form
=
None
self
.
form
_instance
=
None
self
.
resp_status
=
None
self
.
resp_status
=
None
self
.
resp_content
=
None
self
.
resp_headers
=
{}
self
.
resp_headers
=
{}
try
:
try
:
...
@@ -267,30 +299,29 @@ class Resource(object):
...
@@ -267,30 +299,29 @@ class Resource(object):
mimetype
,
emitter
=
self
.
determine_emitter
(
request
)
mimetype
,
emitter
=
self
.
determine_emitter
(
request
)
# Ensure the requested operation is permitted on this resource
# Ensure the requested operation is permitted on this resource
self
.
check_method_allowed
(
self
.
method
)
self
.
check_method_allowed
(
method
)
# Get the appropriate create/read/update/delete function
# Get the appropriate create/read/update/delete function
func
=
getattr
(
self
,
self
.
CALLMAP
.
get
(
self
.
method
,
''
))
func
=
getattr
(
self
,
self
.
CALLMAP
.
get
(
method
,
''
))
# Either generate the response data, deserializing and validating any request data
# Either generate the response data, deserializing and validating any request data
if
self
.
method
in
(
'PUT'
,
'POST'
):
if
method
in
(
'PUT'
,
'POST'
):
parser
=
self
.
determine_parser
(
request
)
parser
=
self
.
determine_parser
(
request
)
data
=
parser
(
self
)
.
parse
(
request
.
raw_post_data
)
data
=
parser
(
self
)
.
parse
(
request
.
raw_post_data
)
self
.
form
=
self
.
determine_form
(
data
)
(
data
,
self
.
form_instance
)
=
self
.
cleanup_request
(
data
)
data
=
self
.
cleanup_request
(
data
)
(
self
.
resp_status
,
ret
,
self
.
resp_headers
)
=
func
(
data
,
request
.
META
,
*
args
,
**
kwargs
)
(
self
.
resp_status
,
ret
,
self
.
resp_headers
)
=
func
(
data
,
request
.
META
,
*
args
,
**
kwargs
)
else
:
else
:
(
self
.
resp_status
,
ret
,
self
.
resp_headers
)
=
func
(
request
.
META
,
*
args
,
**
kwargs
)
(
self
.
resp_status
,
ret
,
self
.
resp_headers
)
=
func
(
request
.
META
,
*
args
,
**
kwargs
)
self
.
form
=
self
.
determine
_form
(
ret
,
is_response
=
True
)
self
.
form
_instance
=
self
.
get_bound
_form
(
ret
,
is_response
=
True
)
except
ResourceException
,
exc
:
except
ResourceException
,
exc
:
(
self
.
resp_status
,
ret
,
self
.
resp_headers
)
=
(
exc
.
status
,
exc
.
content
,
exc
.
headers
)
(
self
.
resp_status
,
ret
,
self
.
resp_headers
)
=
(
exc
.
status
,
exc
.
content
,
exc
.
headers
)
if
emitter
is
None
:
if
emitter
is
None
:
mimetype
,
emitter
=
self
.
emitters
[
0
]
mimetype
,
emitter
=
self
.
emitters
[
0
]
if
self
.
form
is
None
:
if
self
.
form
_instance
is
None
:
self
.
form
=
self
.
determine
_form
()
self
.
form
_instance
=
self
.
get_bound
_form
()
# Always add the allow header
# Always add the allow header
...
@@ -315,17 +346,16 @@ from django.db.models.query import QuerySet
...
@@ -315,17 +346,16 @@ from django.db.models.query import QuerySet
from
django.db.models
import
Model
from
django.db.models
import
Model
import
decimal
import
decimal
import
inspect
import
inspect
import
re
class
ModelResource
(
Resource
):
class
ModelResource
(
Resource
):
model
=
None
model
=
None
fields
=
None
fields
=
None
form_fields
=
None
form_fields
=
None
def
determine
_form
(
self
,
data
=
None
,
is_response
=
False
):
def
get_bound
_form
(
self
,
data
=
None
,
is_response
=
False
):
"""Return a form that may be used in validation and/or rendering an html emitter"""
"""Return a form that may be used in validation and/or rendering an html emitter"""
if
self
.
form
:
if
self
.
form
:
return
super
(
self
.
__class__
,
self
)
.
determine
_form
(
data
,
is_response
=
is_response
)
return
super
(
self
.
__class__
,
self
)
.
get_bound
_form
(
data
,
is_response
=
is_response
)
elif
self
.
model
:
elif
self
.
model
:
class
NewModelForm
(
ModelForm
):
class
NewModelForm
(
ModelForm
):
...
@@ -640,7 +670,7 @@ class ModelResource(Resource):
...
@@ -640,7 +670,7 @@ class ModelResource(Resource):
class
QueryModelResource
(
ModelResource
):
class
QueryModelResource
(
ModelResource
):
allowed_methods
=
(
'read'
,)
allowed_methods
=
(
'read'
,)
def
determine
_form
(
self
,
data
=
None
,
is_response
=
False
):
def
get_bound
_form
(
self
,
data
=
None
,
is_response
=
False
):
return
None
return
None
def
read
(
self
,
headers
=
{},
*
args
,
**
kwargs
):
def
read
(
self
,
headers
=
{},
*
args
,
**
kwargs
):
...
...
src/rest/templates/emitter.html
View file @
764fbe33
...
@@ -7,26 +7,27 @@
...
@@ -7,26 +7,27 @@
pre
{
border
:
1px
solid
black
;
padding
:
1em
;
background
:
#ffd
}
pre
{
border
:
1px
solid
black
;
padding
:
1em
;
background
:
#ffd
}
div
.action
{
padding
:
0.5em
1em
;
margin-bottom
:
0.5em
;
background
:
#ddf
}
div
.action
{
padding
:
0.5em
1em
;
margin-bottom
:
0.5em
;
background
:
#ddf
}
</style>
</style>
<title>
API - {{ resource.name }}
</title>
</head>
</head>
<body>
<body>
<h1>
{{ resource
_
name }}
</h1>
<h1>
{{ resource
.
name }}
</h1>
<p>
{{ resource
_doc
}}
</p>
<p>
{{ resource
.description
}}
</p>
<pre><b>
{{
status }} {{ reason
}}
</b>
{% autoescape off %}
<pre><b>
{{
resource.resp_status }} {{ resource.resp_status_text
}}
</b>
{% autoescape off %}
{% for key, val in headers.items %}
<b>
{{ key }}:
</b>
{{ val|urlize_quoted_links }}
{% for key, val in
resource.resp_
headers.items %}
<b>
{{ key }}:
</b>
{{ val|urlize_quoted_links }}
{% endfor %}
{% endfor %}
{{ content|urlize_quoted_links }}
</pre>
{% endautoescape %}
{{ content|urlize_quoted_links }}
</pre>
{% endautoescape %}
{% if 'read' in resource.allowed_operations %}
{% if 'read' in resource.allowed_operations %}
<div
class=
'action'
>
<div
class=
'action'
>
<a
href=
'{{ request.path }}'
>
Read
</a>
<a
href=
'{{ re
source.re
quest.path }}'
>
Read
</a>
</div>
</div>
{% endif %}
{% endif %}
{% if 'create' in resource.allowed_operations %}
{% if 'create' in resource.allowed_operations %}
<div
class=
'action'
>
<div
class=
'action'
>
<form
action=
"{{ request.path }}"
method=
"POST"
>
<form
action=
"{{ re
source.re
quest.path }}"
method=
"POST"
>
{% csrf_token %}
{% csrf_token %}
{{
create_form
.as_p }}
{{
resource.form_instance
.as_p }}
<input
type=
"submit"
value=
"Create"
/>
<input
type=
"submit"
value=
"Create"
/>
</form>
</form>
</div>
</div>
...
@@ -34,10 +35,10 @@
...
@@ -34,10 +35,10 @@
{% if 'update' in resource.allowed_operations %}
{% if 'update' in resource.allowed_operations %}
<div
class=
'action'
>
<div
class=
'action'
>
<form
action=
"{{ request.path }}"
method=
"POST"
>
<form
action=
"{{ re
source.re
quest.path }}"
method=
"POST"
>
<input
type=
"hidden"
name=
"{{ resource.METHOD_PARAM}}"
value=
"PUT"
/>
<input
type=
"hidden"
name=
"{{ resource.METHOD_PARAM}}"
value=
"PUT"
/>
{% csrf_token %}
{% csrf_token %}
{{
create_form
.as_p }}
{{
resource.form_instance
.as_p }}
<input
type=
"submit"
value=
"Update"
/>
<input
type=
"submit"
value=
"Update"
/>
</form>
</form>
</div>
</div>
...
@@ -45,7 +46,7 @@
...
@@ -45,7 +46,7 @@
{% if 'delete' in resource.allowed_operations %}
{% if 'delete' in resource.allowed_operations %}
<div
class=
'action'
>
<div
class=
'action'
>
<form
action=
"{{ request.path }}"
method=
"POST"
>
<form
action=
"{{ re
source.re
quest.path }}"
method=
"POST"
>
{% csrf_token %}
{% csrf_token %}
<input
type=
"hidden"
name=
"{{ resource.METHOD_PARAM}}"
value=
"DELETE"
/>
<input
type=
"hidden"
name=
"{{ resource.METHOD_PARAM}}"
value=
"DELETE"
/>
<input
type=
"submit"
value=
"Delete"
/>
<input
type=
"submit"
value=
"Delete"
/>
...
...
src/rest/templates/emitter.txt
View file @
764fbe33
{% autoescape off %}HTTP Status {{ status }}
{{ resource.name }}
{% for key, val in headers.items %}{{ key }}: {{ val }}
{{ resource.description }}
{% autoescape off %}HTTP/1.0 {{ resource.resp_status }} {{ resource.resp_status_text }}
{% for key, val in resource.resp_headers.items %}{{ key }}: {{ val }}
{% endfor %}
{% endfor %}
{{ content }}{% endautoescape %}
{{ content }}{% endautoescape %}
src/testapp/views.py
View file @
764fbe33
from
rest.resource
import
Resource
,
ModelResource
,
QueryModelResource
from
rest.resource
import
Resource
,
ModelResource
,
QueryModelResource
from
testapp.models
import
BlogPost
,
Comment
from
testapp.models
import
BlogPost
,
Comment
##### Root Resource #####
class
RootResource
(
Resource
):
class
RootResource
(
Resource
):
"""This is the top level resource for the API.
"""This is the top level resource for the API.
All the sub-resources are discoverable from here."""
All the sub-resources are discoverable from here."""
...
@@ -11,48 +13,52 @@ class RootResource(Resource):
...
@@ -11,48 +13,52 @@ class RootResource(Resource):
'blog-post'
:
self
.
reverse
(
BlogPostCreator
)},
{})
'blog-post'
:
self
.
reverse
(
BlogPostCreator
)},
{})
# Blog Post Resources
##### Blog Post Resources #####
BLOG_POST_FIELDS
=
(
'created'
,
'title'
,
'slug'
,
'content'
,
'absolute_url'
,
'comment_url'
,
'comments_url'
)
class
BlogPostList
(
QueryModelResource
):
class
BlogPostList
(
QueryModelResource
):
"""A resource which lists all existing blog posts."""
"""A resource which lists all existing blog posts."""
allowed_operations
=
(
'read'
,
)
allowed_operations
=
(
'read'
,
)
model
=
BlogPost
model
=
BlogPost
fields
=
BLOG_POST_FIELDS
class
BlogPostCreator
(
ModelResource
):
class
BlogPostCreator
(
ModelResource
):
"""A resource with which blog posts may be created."""
"""A resource with which blog posts may be created."""
allowed_operations
=
(
'create'
,)
allowed_operations
=
(
'create'
,)
model
=
BlogPost
model
=
BlogPost
fields
=
(
'created'
,
'title'
,
'slug'
,
'content'
,
'absolute_url'
,
'comment_url'
,
'comments_url'
)
fields
=
BLOG_POST_FIELDS
class
BlogPostInstance
(
ModelResource
):
class
BlogPostInstance
(
ModelResource
):
"""A resource which represents a single blog post."""
"""A resource which represents a single blog post."""
allowed_operations
=
(
'read'
,
'update'
,
'delete'
)
allowed_operations
=
(
'read'
,
'update'
,
'delete'
)
model
=
BlogPost
model
=
BlogPost
fields
=
(
'created'
,
'title'
,
'slug'
,
'content'
,
'absolute_url'
,
'comment_url'
,
'comments_url'
)
fields
=
BLOG_POST_FIELDS
##### Comment Resources #####
# Comment Resources
COMMENT_FIELDS
=
(
'username'
,
'comment'
,
'created'
,
'rating'
,
'absolute_url'
,
'blogpost_url'
)
class
CommentList
(
QueryModelResource
):
class
CommentList
(
QueryModelResource
):
"""A resource which lists all existing comments for a given blog post."""
"""A resource which lists all existing comments for a given blog post."""
allowed_operations
=
(
'read'
,
)
allowed_operations
=
(
'read'
,
)
model
=
Comment
model
=
Comment
fields
=
COMMENT_FIELDS
class
CommentCreator
(
ModelResource
):
class
CommentCreator
(
ModelResource
):
"""A resource with which blog comments may be created for a given blog post."""
"""A resource with which blog comments may be created for a given blog post."""
allowed_operations
=
(
'create'
,)
allowed_operations
=
(
'create'
,)
model
=
Comment
model
=
Comment
fields
=
(
'username'
,
'comment'
,
'created'
,
'rating'
,
'absolute_url'
,
'blogpost_url'
)
fields
=
COMMENT_FIELDS
class
CommentInstance
(
ModelResource
):
class
CommentInstance
(
ModelResource
):
"""A resource which represents a single comment."""
"""A resource which represents a single comment."""
allowed_operations
=
(
'read'
,
'update'
,
'delete'
)
allowed_operations
=
(
'read'
,
'update'
,
'delete'
)
model
=
Comment
model
=
Comment
fields
=
(
'username'
,
'comment'
,
'created'
,
'rating'
,
'absolute_url'
,
'blogpost_url'
)
fields
=
COMMENT_FIELDS
#
#
#'read-only-api': self.reverse(ReadOnlyResource),
#'read-only-api': self.reverse(ReadOnlyResource),
...
...
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