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
77d061d2
Commit
77d061d2
authored
Jan 28, 2015
by
Brandon Cazander
Committed by
Brandon Cazander
Feb 02, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Provide rest_framework.resolve. Fixes #2489
parent
e63f49bd
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
84 additions
and
8 deletions
+84
-8
rest_framework/relations.py
+4
-3
rest_framework/reverse.py
+14
-1
rest_framework/versioning.py
+16
-0
tests/test_relations.py
+48
-2
tests/urls.py
+2
-2
No files found.
rest_framework/relations.py
View file @
77d061d2
# coding: utf-8
# coding: utf-8
from
__future__
import
unicode_literals
from
__future__
import
unicode_literals
from
django.core.exceptions
import
ObjectDoesNotExist
,
ImproperlyConfigured
from
django.core.exceptions
import
ObjectDoesNotExist
,
ImproperlyConfigured
from
django.core.urlresolvers
import
resolve
,
get_script_prefix
,
NoReverseMatch
,
Resolver404
from
django.core.urlresolvers
import
get_script_prefix
,
NoReverseMatch
,
Resolver404
from
django.db.models.query
import
QuerySet
from
django.db.models.query
import
QuerySet
from
django.utils
import
six
from
django.utils
import
six
from
django.utils.encoding
import
smart_text
from
django.utils.encoding
import
smart_text
...
@@ -9,7 +9,7 @@ from django.utils.six.moves.urllib import parse as urlparse
...
@@ -9,7 +9,7 @@ from django.utils.six.moves.urllib import parse as urlparse
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
rest_framework.compat
import
OrderedDict
from
rest_framework.compat
import
OrderedDict
from
rest_framework.fields
import
get_attribute
,
empty
,
Field
from
rest_framework.fields
import
get_attribute
,
empty
,
Field
from
rest_framework.reverse
import
reverse
from
rest_framework.reverse
import
reverse
,
resolve
from
rest_framework.utils
import
html
from
rest_framework.utils
import
html
...
@@ -205,6 +205,7 @@ class HyperlinkedRelatedField(RelatedField):
...
@@ -205,6 +205,7 @@ class HyperlinkedRelatedField(RelatedField):
return
self
.
reverse
(
view_name
,
kwargs
=
kwargs
,
request
=
request
,
format
=
format
)
return
self
.
reverse
(
view_name
,
kwargs
=
kwargs
,
request
=
request
,
format
=
format
)
def
to_internal_value
(
self
,
data
):
def
to_internal_value
(
self
,
data
):
request
=
self
.
context
.
get
(
'request'
,
None
)
try
:
try
:
http_prefix
=
data
.
startswith
((
'http:'
,
'https:'
))
http_prefix
=
data
.
startswith
((
'http:'
,
'https:'
))
except
AttributeError
:
except
AttributeError
:
...
@@ -218,7 +219,7 @@ class HyperlinkedRelatedField(RelatedField):
...
@@ -218,7 +219,7 @@ class HyperlinkedRelatedField(RelatedField):
data
=
'/'
+
data
[
len
(
prefix
):]
data
=
'/'
+
data
[
len
(
prefix
):]
try
:
try
:
match
=
self
.
resolve
(
data
)
match
=
self
.
resolve
(
data
,
request
=
request
)
except
Resolver404
:
except
Resolver404
:
self
.
fail
(
'no_match'
)
self
.
fail
(
'no_match'
)
...
...
rest_framework/reverse.py
View file @
77d061d2
"""
"""
Provide
reverse functions that return fully qualified URL
s
Provide
urlresolver functions that return fully qualified URLs or view name
s
"""
"""
from
__future__
import
unicode_literals
from
__future__
import
unicode_literals
from
django.core.urlresolvers
import
reverse
as
django_reverse
from
django.core.urlresolvers
import
reverse
as
django_reverse
from
django.core.urlresolvers
import
resolve
as
django_resolve
from
django.utils
import
six
from
django.utils
import
six
from
django.utils.functional
import
lazy
from
django.utils.functional
import
lazy
def
resolve
(
path
,
urlconf
=
None
,
request
=
None
):
"""
If versioning is being used then we pass any `resolve` calls through
to the versioning scheme instance, so that the resulting view name
can be modified if needed.
"""
scheme
=
getattr
(
request
,
'versioning_scheme'
,
None
)
if
scheme
is
not
None
:
return
scheme
.
resolve
(
path
,
urlconf
,
request
)
return
django_resolve
(
path
,
urlconf
)
def
reverse
(
viewname
,
args
=
None
,
kwargs
=
None
,
request
=
None
,
format
=
None
,
**
extra
):
def
reverse
(
viewname
,
args
=
None
,
kwargs
=
None
,
request
=
None
,
format
=
None
,
**
extra
):
"""
"""
If versioning is being used then we pass any `reverse` calls through
If versioning is being used then we pass any `reverse` calls through
...
...
rest_framework/versioning.py
View file @
77d061d2
# coding: utf-8
# coding: utf-8
from
__future__
import
unicode_literals
from
__future__
import
unicode_literals
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.core.urlresolvers
import
resolve
as
django_resolve
from
django.core.urlresolvers
import
ResolverMatch
from
rest_framework
import
exceptions
from
rest_framework
import
exceptions
from
rest_framework.compat
import
unicode_http_header
from
rest_framework.compat
import
unicode_http_header
from
rest_framework.reverse
import
_reverse
from
rest_framework.reverse
import
_reverse
...
@@ -24,6 +26,9 @@ class BaseVersioning(object):
...
@@ -24,6 +26,9 @@ class BaseVersioning(object):
def
reverse
(
self
,
viewname
,
args
=
None
,
kwargs
=
None
,
request
=
None
,
format
=
None
,
**
extra
):
def
reverse
(
self
,
viewname
,
args
=
None
,
kwargs
=
None
,
request
=
None
,
format
=
None
,
**
extra
):
return
_reverse
(
viewname
,
args
,
kwargs
,
request
,
format
,
**
extra
)
return
_reverse
(
viewname
,
args
,
kwargs
,
request
,
format
,
**
extra
)
def
resolve
(
self
,
path
,
urlconf
=
None
):
return
django_resolve
(
path
,
urlconf
)
def
is_allowed_version
(
self
,
version
):
def
is_allowed_version
(
self
,
version
):
if
not
self
.
allowed_versions
:
if
not
self
.
allowed_versions
:
return
True
return
True
...
@@ -127,6 +132,17 @@ class NamespaceVersioning(BaseVersioning):
...
@@ -127,6 +132,17 @@ class NamespaceVersioning(BaseVersioning):
viewname
,
args
,
kwargs
,
request
,
format
,
**
extra
viewname
,
args
,
kwargs
,
request
,
format
,
**
extra
)
)
def
resolve
(
self
,
path
,
urlconf
=
None
,
request
=
None
):
match
=
django_resolve
(
path
,
urlconf
)
if
match
.
namespace
:
_
,
view_name
=
match
.
view_name
.
split
(
':'
)
return
ResolverMatch
(
func
=
match
.
func
,
args
=
match
.
args
,
kwargs
=
match
.
kwargs
,
url_name
=
view_name
,
app_name
=
match
.
app_name
)
return
match
class
HostNameVersioning
(
BaseVersioning
):
class
HostNameVersioning
(
BaseVersioning
):
"""
"""
...
...
tests/test_relations.py
View file @
77d061d2
from
.utils
import
mock_reverse
,
fail_reverse
,
BadType
,
MockObject
,
MockQueryset
from
.utils
import
mock_reverse
,
fail_reverse
,
BadType
,
MockObject
,
MockQueryset
from
django.core.exceptions
import
ImproperlyConfigured
from
django.conf.urls
import
patterns
,
url
,
include
from
django.core.exceptions
import
ImproperlyConfigured
,
ObjectDoesNotExist
from
django.utils.datastructures
import
MultiValueDict
from
django.utils.datastructures
import
MultiValueDict
from
rest_framework
import
serializers
from
rest_framework
import
serializers
from
rest_framework.fields
import
empty
from
rest_framework.fields
import
empty
from
rest_framework.test
import
APISimpleTestCase
from
rest_framework.test
import
APISimpleTestCase
,
APIRequestFactory
from
rest_framework.versioning
import
NamespaceVersioning
import
pytest
import
pytest
factory
=
APIRequestFactory
()
request
=
factory
.
get
(
'/'
)
# Just to ensure we have a request in the serializer context
dummy_view
=
lambda
request
,
pk
:
None
included_patterns
=
[
url
(
r'^example/(?P<pk>\d+)/$'
,
dummy_view
,
name
=
'example-detail'
)
]
urlpatterns
=
patterns
(
''
,
url
(
r'^v1/'
,
include
(
included_patterns
,
namespace
=
'v1'
)),
url
(
r'^example/(?P<pk>\d+)/$'
,
dummy_view
,
name
=
'example-detail'
)
)
class
TestStringRelatedField
(
APISimpleTestCase
):
class
TestStringRelatedField
(
APISimpleTestCase
):
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -48,6 +65,35 @@ class TestPrimaryKeyRelatedField(APISimpleTestCase):
...
@@ -48,6 +65,35 @@ class TestPrimaryKeyRelatedField(APISimpleTestCase):
assert
representation
==
self
.
instance
.
pk
assert
representation
==
self
.
instance
.
pk
class
TestHyperlinkedRelatedField
(
APISimpleTestCase
):
urls
=
'tests.test_relations'
def
setUp
(
self
):
class
HyperlinkedMockQueryset
(
MockQueryset
):
def
get
(
self
,
**
lookup
):
for
item
in
self
.
items
:
if
item
.
pk
==
int
(
lookup
.
get
(
'pk'
,
-
1
)):
return
item
raise
ObjectDoesNotExist
()
self
.
queryset
=
HyperlinkedMockQueryset
([
MockObject
(
pk
=
1
,
name
=
'foo'
),
MockObject
(
pk
=
2
,
name
=
'bar'
),
MockObject
(
pk
=
3
,
name
=
'baz'
)
])
self
.
field
=
serializers
.
HyperlinkedRelatedField
(
view_name
=
'example-detail'
,
queryset
=
self
.
queryset
)
request
=
factory
.
post
(
'/'
)
request
.
versioning_scheme
=
NamespaceVersioning
()
self
.
field
.
_context
=
{
'request'
:
request
}
def
test_bug_2489
(
self
):
self
.
field
.
to_internal_value
(
'/example/3/'
)
self
.
field
.
to_internal_value
(
'/v1/example/3/'
)
class
TestHyperlinkedIdentityField
(
APISimpleTestCase
):
class
TestHyperlinkedIdentityField
(
APISimpleTestCase
):
def
setUp
(
self
):
def
setUp
(
self
):
self
.
instance
=
MockObject
(
pk
=
1
,
name
=
'foo'
)
self
.
instance
=
MockObject
(
pk
=
1
,
name
=
'foo'
)
...
...
tests/urls.py
View file @
77d061d2
"""
"""
Blank URLConf just to keep the test suite happy
Blank URLConf just to keep the test suite happy
"""
"""
from
django.conf.urls
import
patter
ns
from
tests
import
test_relatio
ns
urlpatterns
=
patterns
(
''
)
urlpatterns
=
test_relations
.
urlpatterns
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