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
abc7439f
Commit
abc7439f
authored
Jan 03, 2012
by
Sebastian Żurek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
QueryMixin created + related mixins updates
parent
ccbb5368
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
98 additions
and
39 deletions
+98
-39
djangorestframework/mixins.py
+98
-39
No files found.
djangorestframework/mixins.py
View file @
abc7439f
...
@@ -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
djangorestframework
import
status
from
djangorestframework
import
status
...
@@ -35,6 +36,82 @@ __all__ = (
...
@@ -35,6 +36,82 @@ __all__ = (
)
)
#### Base for *ModelMixins using URL arguments to filter out queryset or instances ####
class
QueryMixin
(
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`
"""
def
build_query
(
self
,
*
args
,
**
kwargs
):
# This methods simply mimics the previous behaviour of the framework, where
# the following code was used few times in to retrive the instance:
#
# ------------------------------
# if args:
# #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)
# -----------------------------
#
# this block is now replaced with
#
# -------------
# instance = model.objects.get(self.build_query(*args, **kwargs)
# -------------
#
# which is more DRY + gives the simple possibility to provide
# *any* arguments in URL
#
tmp
=
dict
(
kwargs
)
if
args
:
# While this code simply follows the previous behaviour, we feel this
# is somehow strange to use 'pk' with any other query parameters... isn't it?
# 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
,
*
args
,
**
kwargs
):
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
())
if
args
:
all_kw_args
.
update
({
'pk'
:
args
[
-
1
]})
return
all_kw_args
# TODO: get_object and get_queryset methods should be implemented somehow. This will
# give a nice parallel to django class-based generic views. We're leaving this
# unimplementd at the moment.
def
get_object
(
self
):
pass
def
get_queryset
(
self
):
pass
########## Request Mixin ##########
########## Request Mixin ##########
class
RequestMixin
(
object
):
class
RequestMixin
(
object
):
...
@@ -481,7 +558,7 @@ class InstanceMixin(object):
...
@@ -481,7 +558,7 @@ class InstanceMixin(object):
########## Model Mixins ##########
########## Model Mixins ##########
class
ReadModelMixin
(
object
):
class
ReadModelMixin
(
QueryMixin
):
"""
"""
Behavior to read a `model` instance on GET requests
Behavior to read a `model` instance on GET requests
"""
"""
...
@@ -489,22 +566,21 @@ class ReadModelMixin(object):
...
@@ -489,22 +566,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
(
QueryMixin
):
"""
"""
Behavior to create a `model` instance on POST requests
Behavior to create a `model` instance on POST requests
"""
"""
...
@@ -515,11 +591,6 @@ class CreateModelMixin(object):
...
@@ -515,11 +591,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
):
...
@@ -528,12 +599,8 @@ class CreateModelMixin(object):
...
@@ -528,12 +599,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
:
...
@@ -555,7 +622,7 @@ class CreateModelMixin(object):
...
@@ -555,7 +622,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
(
QueryMixin
):
"""
"""
Behavior to update a `model` instance on PUT requests
Behavior to update a `model` instance on PUT requests
"""
"""
...
@@ -564,24 +631,21 @@ class UpdateModelMixin(object):
...
@@ -564,24 +631,21 @@ 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
()
# args + kwartgs were not provided...
# self.model_instance = model(**self.CONTENT)
# 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
(
QueryMixin
):
"""
"""
Behavior to delete a `model` instance on DELETE requests
Behavior to delete a `model` instance on DELETE requests
"""
"""
...
@@ -589,12 +653,7 @@ class DeleteModelMixin(object):
...
@@ -589,12 +653,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
,
{})
...
@@ -602,7 +661,7 @@ class DeleteModelMixin(object):
...
@@ -602,7 +661,7 @@ class DeleteModelMixin(object):
return
return
class
ListModelMixin
(
object
):
class
ListModelMixin
(
QueryMixin
):
"""
"""
Behavior to list a set of `model` instances on GET requests
Behavior to list a set of `model` instances on GET requests
"""
"""
...
@@ -634,7 +693,7 @@ class ListModelMixin(object):
...
@@ -634,7 +693,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