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
dacc9c0f
Commit
dacc9c0f
authored
Jan 11, 2012
by
Tom Christie
Browse files
Options
Browse Files
Download
Plain Diff
Merge
https://github.com/sebzur/django-rest-framework
parents
97c5262e
86b1495c
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
87 additions
and
40 deletions
+87
-40
djangorestframework/mixins.py
+87
-40
No files found.
djangorestframework/mixins.py
View file @
dacc9c0f
...
@@ -6,6 +6,7 @@ classes that can be added to a `View`.
...
@@ -6,6 +6,7 @@ classes that can be added to a `View`.
from
django.contrib.auth.models
import
AnonymousUser
from
django.contrib.auth.models
import
AnonymousUser
from
django.core.paginator
import
Paginator
from
django.core.paginator
import
Paginator
from
django.db.models.fields.related
import
ForeignKey
from
django.db.models.fields.related
import
ForeignKey
from
django.db.models.query
import
Q
from
django.http
import
HttpResponse
from
django.http
import
HttpResponse
from
urlobject
import
URLObject
from
urlobject
import
URLObject
...
@@ -482,7 +483,75 @@ class InstanceMixin(object):
...
@@ -482,7 +483,75 @@ class InstanceMixin(object):
########## Model Mixins ##########
########## Model Mixins ##########
class
ReadModelMixin
(
object
):
class
ModelMixin
(
object
):
""" Implements mechanisms used by other classes (like *ModelMixin group) to
define a query that represents Model instances the Mixin is working with.
If a *ModelMixin is going to retrive an instance (or queryset) using args and kwargs
passed by as URL arguments, it should provied arguments to objects.get and objects.filter
methods wrapped in by `build_query`
If a *ModelMixin is going to create/update an instance get_instance_data handles the instance
data creation/preaparation.
"""
def
build_query
(
self
,
*
args
,
**
kwargs
):
""" Returns django.db.models.Q object to be used for the objects retrival.
Arguments:
- args: unnamed URL arguments
- kwargs: named URL arguments
If a URL passes any arguments to the view being the QueryMixin subclass
build_query manages the arguments and provides the Q object that will be
used for the objects retrival with filter/get queryset methods.
Technically, neither args nor kwargs have to be provided, however the default
behaviour is to map all kwargs as the query constructors so that if this
method is not overriden only kwargs keys being model fields are valid.
If args are provided, the last one (args[-1) is understood as instance pk. This
should be removed in the future, though.
"""
tmp
=
dict
(
kwargs
)
if
args
:
# If we have any none kwargs then assume the last represents the primrary key
# Otherwise assume the kwargs uniquely identify the model
tmp
.
update
({
'pk'
:
args
[
-
1
]})
return
Q
(
**
tmp
)
def
get_instance_data
(
self
,
model
,
content
,
**
kwargs
):
""" Returns the dict with the data for model instance creation/update query.
Arguments:
- model: model class (django.db.models.Model subclass) to work with
- content: a dictionary with instance data
- kwargs: a dict of URL provided keyword arguments
The create/update queries are created basicly with the contet provided
with POST/PUT HTML methods and kwargs passed in the URL. This methods simply merges
the URL data and the content preaparing the ready-to-use data dictionary.
"""
tmp
=
dict
(
kwargs
)
for
field
in
model
.
_meta
.
fields
:
if
isinstance
(
field
,
ForeignKey
)
and
tmp
.
has_key
(
field
.
name
):
# translate 'related_field' kwargs into 'related_field_id'
tmp
[
field
.
name
+
'_id'
]
=
tmp
[
field
.
name
]
del
tmp
[
field
.
name
]
all_kw_args
=
dict
(
content
.
items
()
+
tmp
.
items
())
return
all_kw_args
class
ReadModelMixin
(
ModelMixin
):
"""
"""
Behavior to read a `model` instance on GET requests
Behavior to read a `model` instance on GET requests
"""
"""
...
@@ -490,22 +559,21 @@ class ReadModelMixin(object):
...
@@ -490,22 +559,21 @@ class ReadModelMixin(object):
model
=
self
.
resource
.
model
model
=
self
.
resource
.
model
try
:
try
:
if
args
:
self
.
model_instance
=
model
.
objects
.
get
(
self
.
build_query
(
*
args
,
**
kwargs
))
# If we have any none kwargs then assume the last represents the primrary key
self
.
model_instance
=
model
.
objects
.
get
(
pk
=
args
[
-
1
],
**
kwargs
)
else
:
# Otherwise assume the kwargs uniquely identify the model
filtered_keywords
=
kwargs
.
copy
()
if
BaseRenderer
.
_FORMAT_QUERY_PARAM
in
filtered_keywords
:
del
filtered_keywords
[
BaseRenderer
.
_FORMAT_QUERY_PARAM
]
self
.
model_instance
=
model
.
objects
.
get
(
**
filtered_keywords
)
except
model
.
DoesNotExist
:
except
model
.
DoesNotExist
:
raise
ErrorResponse
(
status
.
HTTP_404_NOT_FOUND
)
raise
ErrorResponse
(
status
.
HTTP_404_NOT_FOUND
)
return
self
.
model_instance
return
self
.
model_instance
def
build_query
(
self
,
*
args
,
**
kwargs
):
# Build query is overriden to filter the kwargs priori
# to use them as build_query argument
filtered_keywords
=
kwargs
.
copy
()
if
BaseRenderer
.
_FORMAT_QUERY_PARAM
in
filtered_keywords
:
del
filtered_keywords
[
BaseRenderer
.
_FORMAT_QUERY_PARAM
]
return
super
(
ReadModelMixin
,
self
)
.
build_query
(
*
args
,
**
filtered_keywords
)
class
CreateModelMixin
(
object
):
class
CreateModelMixin
(
ModelMixin
):
"""
"""
Behavior to create a `model` instance on POST requests
Behavior to create a `model` instance on POST requests
"""
"""
...
@@ -516,11 +584,6 @@ class CreateModelMixin(object):
...
@@ -516,11 +584,6 @@ class CreateModelMixin(object):
content
=
dict
(
self
.
CONTENT
)
content
=
dict
(
self
.
CONTENT
)
m2m_data
=
{}
m2m_data
=
{}
for
field
in
model
.
_meta
.
fields
:
if
isinstance
(
field
,
ForeignKey
)
and
kwargs
.
has_key
(
field
.
name
):
# translate 'related_field' kwargs into 'related_field_id'
kwargs
[
field
.
name
+
'_id'
]
=
kwargs
[
field
.
name
]
del
kwargs
[
field
.
name
]
for
field
in
model
.
_meta
.
many_to_many
:
for
field
in
model
.
_meta
.
many_to_many
:
if
content
.
has_key
(
field
.
name
):
if
content
.
has_key
(
field
.
name
):
...
@@ -529,12 +592,8 @@ class CreateModelMixin(object):
...
@@ -529,12 +592,8 @@ class CreateModelMixin(object):
)
)
del
content
[
field
.
name
]
del
content
[
field
.
name
]
all_kw_args
=
dict
(
content
.
items
()
+
kwargs
.
items
())
if
args
:
instance
=
model
(
**
self
.
get_instance_data
(
model
,
content
,
*
args
,
**
kwargs
))
instance
=
model
(
pk
=
args
[
-
1
],
**
all_kw_args
)
else
:
instance
=
model
(
**
all_kw_args
)
instance
.
save
()
instance
.
save
()
for
fieldname
in
m2m_data
:
for
fieldname
in
m2m_data
:
...
@@ -556,7 +615,7 @@ class CreateModelMixin(object):
...
@@ -556,7 +615,7 @@ class CreateModelMixin(object):
return
Response
(
status
.
HTTP_201_CREATED
,
instance
,
headers
)
return
Response
(
status
.
HTTP_201_CREATED
,
instance
,
headers
)
class
UpdateModelMixin
(
object
):
class
UpdateModelMixin
(
ModelMixin
):
"""
"""
Behavior to update a `model` instance on PUT requests
Behavior to update a `model` instance on PUT requests
"""
"""
...
@@ -565,24 +624,17 @@ class UpdateModelMixin(object):
...
@@ -565,24 +624,17 @@ class UpdateModelMixin(object):
# 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
# 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
:
try
:
if
args
:
self
.
model_instance
=
model
.
objects
.
get
(
self
.
build_query
(
*
args
,
**
kwargs
))
# If we have any none kwargs then assume the last represents the primary key
self
.
model_instance
=
model
.
objects
.
get
(
pk
=
args
[
-
1
],
**
kwargs
)
else
:
# Otherwise assume the kwargs uniquely identify the model
self
.
model_instance
=
model
.
objects
.
get
(
**
kwargs
)
for
(
key
,
val
)
in
self
.
CONTENT
.
items
():
for
(
key
,
val
)
in
self
.
CONTENT
.
items
():
setattr
(
self
.
model_instance
,
key
,
val
)
setattr
(
self
.
model_instance
,
key
,
val
)
except
model
.
DoesNotExist
:
except
model
.
DoesNotExist
:
self
.
model_instance
=
model
(
**
self
.
CONTENT
)
self
.
model_instance
=
model
(
**
self
.
get_instance_data
(
model
,
self
.
CONTENT
,
*
args
,
**
kwargs
))
self
.
model_instance
.
save
()
self
.
model_instance
.
save
()
self
.
model_instance
.
save
()
return
self
.
model_instance
return
self
.
model_instance
class
DeleteModelMixin
(
object
):
class
DeleteModelMixin
(
ModelMixin
):
"""
"""
Behavior to delete a `model` instance on DELETE requests
Behavior to delete a `model` instance on DELETE requests
"""
"""
...
@@ -590,12 +642,7 @@ class DeleteModelMixin(object):
...
@@ -590,12 +642,7 @@ class DeleteModelMixin(object):
model
=
self
.
resource
.
model
model
=
self
.
resource
.
model
try
:
try
:
if
args
:
instance
=
model
.
objects
.
get
(
self
.
build_query
(
*
args
,
**
kwargs
))
# If we have any none kwargs then assume the last represents the primrary key
instance
=
model
.
objects
.
get
(
pk
=
args
[
-
1
],
**
kwargs
)
else
:
# Otherwise assume the kwargs uniquely identify the model
instance
=
model
.
objects
.
get
(
**
kwargs
)
except
model
.
DoesNotExist
:
except
model
.
DoesNotExist
:
raise
ErrorResponse
(
status
.
HTTP_404_NOT_FOUND
,
None
,
{})
raise
ErrorResponse
(
status
.
HTTP_404_NOT_FOUND
,
None
,
{})
...
@@ -603,7 +650,7 @@ class DeleteModelMixin(object):
...
@@ -603,7 +650,7 @@ class DeleteModelMixin(object):
return
return
class
ListModelMixin
(
object
):
class
ListModelMixin
(
ModelMixin
):
"""
"""
Behavior to list a set of `model` instances on GET requests
Behavior to list a set of `model` instances on GET requests
"""
"""
...
@@ -635,7 +682,7 @@ class ListModelMixin(object):
...
@@ -635,7 +682,7 @@ class ListModelMixin(object):
if
ordering
:
if
ordering
:
args
=
as_tuple
(
ordering
)
args
=
as_tuple
(
ordering
)
queryset
=
queryset
.
order_by
(
*
args
)
queryset
=
queryset
.
order_by
(
*
args
)
return
queryset
.
filter
(
**
kwargs
)
return
queryset
.
filter
(
self
.
build_query
(
**
kwargs
)
)
########## Pagination Mixins ##########
########## Pagination Mixins ##########
...
...
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