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
250755de
Commit
250755de
authored
Sep 12, 2014
by
Tom Christie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Clean up relational fields queryset usage
parent
6db3356c
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
49 additions
and
45 deletions
+49
-45
rest_framework/fields.py
+6
-9
rest_framework/generics.py
+1
-1
rest_framework/relations.py
+39
-34
tests/test_generics.py
+3
-1
No files found.
rest_framework/fields.py
View file @
250755de
...
@@ -508,7 +508,7 @@ class DecimalField(Field):
...
@@ -508,7 +508,7 @@ class DecimalField(Field):
class
DateField
(
Field
):
class
DateField
(
Field
):
default_error_messages
=
{
default_error_messages
=
{
'invalid'
:
_
(
"Date has wrong format. Use one of these formats instead:
%
s"
),
'invalid'
:
_
(
'Date has wrong format. Use one of these formats instead: {format}'
),
}
}
input_formats
=
api_settings
.
DATE_INPUT_FORMATS
input_formats
=
api_settings
.
DATE_INPUT_FORMATS
format
=
api_settings
.
DATE_FORMAT
format
=
api_settings
.
DATE_FORMAT
...
@@ -551,8 +551,7 @@ class DateField(Field):
...
@@ -551,8 +551,7 @@ class DateField(Field):
return
parsed
.
date
()
return
parsed
.
date
()
humanized_format
=
humanize_datetime
.
date_formats
(
self
.
input_formats
)
humanized_format
=
humanize_datetime
.
date_formats
(
self
.
input_formats
)
msg
=
self
.
error_messages
[
'invalid'
]
%
humanized_format
self
.
fail
(
'invalid'
,
format
=
humanized_format
)
raise
ValidationError
(
msg
)
def
to_representation
(
self
,
value
):
def
to_representation
(
self
,
value
):
if
value
is
None
or
self
.
format
is
None
:
if
value
is
None
or
self
.
format
is
None
:
...
@@ -568,7 +567,7 @@ class DateField(Field):
...
@@ -568,7 +567,7 @@ class DateField(Field):
class
DateTimeField
(
Field
):
class
DateTimeField
(
Field
):
default_error_messages
=
{
default_error_messages
=
{
'invalid'
:
_
(
"Datetime has wrong format. Use one of these formats instead:
%
s"
),
'invalid'
:
_
(
'Datetime has wrong format. Use one of these formats instead: {format}'
),
}
}
input_formats
=
api_settings
.
DATETIME_INPUT_FORMATS
input_formats
=
api_settings
.
DATETIME_INPUT_FORMATS
format
=
api_settings
.
DATETIME_FORMAT
format
=
api_settings
.
DATETIME_FORMAT
...
@@ -617,8 +616,7 @@ class DateTimeField(Field):
...
@@ -617,8 +616,7 @@ class DateTimeField(Field):
return
parsed
return
parsed
humanized_format
=
humanize_datetime
.
datetime_formats
(
self
.
input_formats
)
humanized_format
=
humanize_datetime
.
datetime_formats
(
self
.
input_formats
)
msg
=
self
.
error_messages
[
'invalid'
]
%
humanized_format
self
.
fail
(
'invalid'
,
format
=
humanized_format
)
raise
ValidationError
(
msg
)
def
to_representation
(
self
,
value
):
def
to_representation
(
self
,
value
):
if
value
is
None
or
self
.
format
is
None
:
if
value
is
None
or
self
.
format
is
None
:
...
@@ -634,7 +632,7 @@ class DateTimeField(Field):
...
@@ -634,7 +632,7 @@ class DateTimeField(Field):
class
TimeField
(
Field
):
class
TimeField
(
Field
):
default_error_messages
=
{
default_error_messages
=
{
'invalid'
:
_
(
"Time has wrong format. Use one of these formats instead:
%
s"
),
'invalid'
:
_
(
'Time has wrong format. Use one of these formats instead: {format}'
),
}
}
input_formats
=
api_settings
.
TIME_INPUT_FORMATS
input_formats
=
api_settings
.
TIME_INPUT_FORMATS
format
=
api_settings
.
TIME_FORMAT
format
=
api_settings
.
TIME_FORMAT
...
@@ -669,8 +667,7 @@ class TimeField(Field):
...
@@ -669,8 +667,7 @@ class TimeField(Field):
return
parsed
.
time
()
return
parsed
.
time
()
humanized_format
=
humanize_datetime
.
time_formats
(
self
.
input_formats
)
humanized_format
=
humanize_datetime
.
time_formats
(
self
.
input_formats
)
msg
=
self
.
error_messages
[
'invalid'
]
%
humanized_format
self
.
fail
(
'invalid'
,
format
=
humanized_format
)
raise
ValidationError
(
msg
)
def
to_representation
(
self
,
value
):
def
to_representation
(
self
,
value
):
if
value
is
None
or
self
.
format
is
None
:
if
value
is
None
or
self
.
format
is
None
:
...
...
rest_framework/generics.py
View file @
250755de
...
@@ -216,7 +216,7 @@ class GenericAPIView(views.APIView):
...
@@ -216,7 +216,7 @@ class GenericAPIView(views.APIView):
)
)
queryset
=
self
.
queryset
queryset
=
self
.
queryset
if
isinstance
(
self
.
queryset
,
QuerySet
):
if
isinstance
(
queryset
,
QuerySet
):
# Ensure queryset is re-evaluated on each request.
# Ensure queryset is re-evaluated on each request.
queryset
=
queryset
.
all
()
queryset
=
queryset
.
all
()
return
queryset
return
queryset
...
...
rest_framework/relations.py
View file @
250755de
...
@@ -2,28 +2,35 @@ from rest_framework.fields import Field
...
@@ -2,28 +2,35 @@ from rest_framework.fields import Field
from
rest_framework.reverse
import
reverse
from
rest_framework.reverse
import
reverse
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.core.urlresolvers
import
resolve
,
get_script_prefix
,
NoReverseMatch
from
django.core.urlresolvers
import
resolve
,
get_script_prefix
,
NoReverseMatch
from
django.db.models.query
import
QuerySet
from
rest_framework.compat
import
urlparse
from
rest_framework.compat
import
urlparse
def
get_default_queryset
(
serializer_class
,
field_name
):
manager
=
getattr
(
serializer_class
.
opts
.
model
,
field_name
)
if
hasattr
(
manager
,
'related'
):
# Forward relationships
return
manager
.
related
.
model
.
_default_manager
.
all
()
# Reverse relationships
return
manager
.
field
.
rel
.
to
.
_default_manager
.
all
()
class
RelatedField
(
Field
):
class
RelatedField
(
Field
):
def
__init__
(
self
,
**
kwargs
):
def
__init__
(
self
,
**
kwargs
):
self
.
queryset
=
kwargs
.
pop
(
'queryset'
,
None
)
self
.
queryset
=
kwargs
.
pop
(
'queryset'
,
None
)
self
.
many
=
kwargs
.
pop
(
'many'
,
False
)
self
.
many
=
kwargs
.
pop
(
'many'
,
False
)
assert
self
.
queryset
is
not
None
or
kwargs
.
get
(
'read_only'
,
False
),
(
'Relational field must provide a `queryset` argument, '
'or set read_only=`True`.'
)
super
(
RelatedField
,
self
)
.
__init__
(
**
kwargs
)
super
(
RelatedField
,
self
)
.
__init__
(
**
kwargs
)
def
bind
(
self
,
field_name
,
parent
,
root
):
def
get_queryset
(
self
):
super
(
RelatedField
,
self
)
.
bind
(
field_name
,
parent
,
root
)
queryset
=
self
.
queryset
if
self
.
queryset
is
None
and
not
self
.
read_only
:
if
isinstance
(
queryset
,
QuerySet
):
self
.
queryset
=
get_default_queryset
(
parent
,
self
.
source
)
# Ensure queryset is re-evaluated whenever used.
queryset
=
queryset
.
all
()
return
queryset
class
StringRelatedField
(
Field
):
def
__init__
(
self
,
**
kwargs
):
kwargs
[
'read_only'
]
=
True
super
(
StringRelatedField
,
self
)
.
__init__
(
**
kwargs
)
def
to_representation
(
self
,
value
):
return
str
(
value
)
class
PrimaryKeyRelatedField
(
RelatedField
):
class
PrimaryKeyRelatedField
(
RelatedField
):
...
@@ -33,9 +40,9 @@ class PrimaryKeyRelatedField(RelatedField):
...
@@ -33,9 +40,9 @@ class PrimaryKeyRelatedField(RelatedField):
'incorrect_type'
:
'Incorrect type. Expected pk value, received {data_type}.'
,
'incorrect_type'
:
'Incorrect type. Expected pk value, received {data_type}.'
,
}
}
def
from_nativ
e
(
self
,
data
):
def
to_internal_valu
e
(
self
,
data
):
try
:
try
:
return
self
.
queryset
.
get
(
pk
=
data
)
return
self
.
get_queryset
()
.
get
(
pk
=
data
)
except
ObjectDoesNotExist
:
except
ObjectDoesNotExist
:
self
.
fail
(
'does_not_exist'
,
pk_value
=
data
)
self
.
fail
(
'does_not_exist'
,
pk_value
=
data
)
except
(
TypeError
,
ValueError
):
except
(
TypeError
,
ValueError
):
...
@@ -68,9 +75,9 @@ class HyperlinkedRelatedField(RelatedField):
...
@@ -68,9 +75,9 @@ class HyperlinkedRelatedField(RelatedField):
"""
"""
lookup_value
=
view_kwargs
[
self
.
lookup_url_kwarg
]
lookup_value
=
view_kwargs
[
self
.
lookup_url_kwarg
]
lookup_kwargs
=
{
self
.
lookup_field
:
lookup_value
}
lookup_kwargs
=
{
self
.
lookup_field
:
lookup_value
}
return
self
.
queryset
.
get
(
**
lookup_kwargs
)
return
self
.
get_queryset
()
.
get
(
**
lookup_kwargs
)
def
from_nativ
e
(
self
,
value
):
def
to_internal_valu
e
(
self
,
value
):
try
:
try
:
http_prefix
=
value
.
startswith
((
'http:'
,
'https:'
))
http_prefix
=
value
.
startswith
((
'http:'
,
'https:'
))
except
AttributeError
:
except
AttributeError
:
...
@@ -102,13 +109,26 @@ class HyperlinkedIdentityField(RelatedField):
...
@@ -102,13 +109,26 @@ class HyperlinkedIdentityField(RelatedField):
def
__init__
(
self
,
**
kwargs
):
def
__init__
(
self
,
**
kwargs
):
kwargs
[
'read_only'
]
=
True
kwargs
[
'read_only'
]
=
True
kwargs
[
'source'
]
=
'*'
self
.
view_name
=
kwargs
.
pop
(
'view_name'
)
self
.
view_name
=
kwargs
.
pop
(
'view_name'
)
self
.
lookup_field
=
kwargs
.
pop
(
'lookup_field'
,
self
.
lookup_field
)
self
.
lookup_field
=
kwargs
.
pop
(
'lookup_field'
,
self
.
lookup_field
)
self
.
lookup_url_kwarg
=
kwargs
.
pop
(
'lookup_url_kwarg'
,
self
.
lookup_field
)
self
.
lookup_url_kwarg
=
kwargs
.
pop
(
'lookup_url_kwarg'
,
self
.
lookup_field
)
super
(
HyperlinkedIdentityField
,
self
)
.
__init__
(
**
kwargs
)
super
(
HyperlinkedIdentityField
,
self
)
.
__init__
(
**
kwargs
)
def
get_attribute
(
self
,
instance
):
def
get_url
(
self
,
obj
,
view_name
,
request
,
format
):
return
instance
"""
Given an object, return the URL that hyperlinks to the object.
May raise a `NoReverseMatch` if the `view_name` and `lookup_field`
attributes are not configured to correctly match the URL conf.
"""
# Unsaved objects will not yet have a valid URL.
if
obj
.
pk
is
None
:
return
None
lookup_value
=
getattr
(
obj
,
self
.
lookup_field
)
kwargs
=
{
self
.
lookup_url_kwarg
:
lookup_value
}
return
reverse
(
view_name
,
kwargs
=
kwargs
,
request
=
request
,
format
=
format
)
def
to_representation
(
self
,
value
):
def
to_representation
(
self
,
value
):
request
=
self
.
context
.
get
(
'request'
,
None
)
request
=
self
.
context
.
get
(
'request'
,
None
)
...
@@ -144,21 +164,6 @@ class HyperlinkedIdentityField(RelatedField):
...
@@ -144,21 +164,6 @@ class HyperlinkedIdentityField(RelatedField):
)
)
raise
Exception
(
msg
%
self
.
view_name
)
raise
Exception
(
msg
%
self
.
view_name
)
def
get_url
(
self
,
obj
,
view_name
,
request
,
format
):
"""
Given an object, return the URL that hyperlinks to the object.
May raise a `NoReverseMatch` if the `view_name` and `lookup_field`
attributes are not configured to correctly match the URL conf.
"""
# Unsaved objects will not yet have a valid URL.
if
obj
.
pk
is
None
:
return
None
lookup_value
=
getattr
(
obj
,
self
.
lookup_field
)
kwargs
=
{
self
.
lookup_url_kwarg
:
lookup_value
}
return
reverse
(
view_name
,
kwargs
=
kwargs
,
request
=
request
,
format
=
format
)
class
SlugRelatedField
(
RelatedField
):
class
SlugRelatedField
(
RelatedField
):
def
__init__
(
self
,
**
kwargs
):
def
__init__
(
self
,
**
kwargs
):
...
...
tests/test_generics.py
View file @
250755de
...
@@ -547,7 +547,9 @@ class ClassA(models.Model):
...
@@ -547,7 +547,9 @@ class ClassA(models.Model):
class
ClassASerializer
(
serializers
.
ModelSerializer
):
class
ClassASerializer
(
serializers
.
ModelSerializer
):
childs
=
serializers
.
PrimaryKeyRelatedField
(
many
=
True
,
source
=
'childs'
)
childs
=
serializers
.
PrimaryKeyRelatedField
(
many
=
True
,
queryset
=
ClassB
.
objects
.
all
()
)
class
Meta
:
class
Meta
:
model
=
ClassA
model
=
ClassA
...
...
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