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
8d0a91b0
Commit
8d0a91b0
authored
Oct 13, 2016
by
Tom Christie
Committed by
GitHub
Oct 13, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix 3674 (#4571)
Handle ModelSerializer case for relationships to models with custom pk.
parent
88c6c380
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
80 additions
and
7 deletions
+80
-7
rest_framework/serializers.py
+1
-1
rest_framework/utils/field_mapping.py
+1
-1
rest_framework/utils/model_meta.py
+10
-5
tests/test_model_serializer.py
+68
-0
No files found.
rest_framework/serializers.py
View file @
8d0a91b0
...
@@ -1167,7 +1167,7 @@ class ModelSerializer(Serializer):
...
@@ -1167,7 +1167,7 @@ class ModelSerializer(Serializer):
field_kwargs
=
get_relation_kwargs
(
field_name
,
relation_info
)
field_kwargs
=
get_relation_kwargs
(
field_name
,
relation_info
)
to_field
=
field_kwargs
.
pop
(
'to_field'
,
None
)
to_field
=
field_kwargs
.
pop
(
'to_field'
,
None
)
if
to_field
and
not
relation_info
.
related_model
.
_meta
.
get_field
(
to_field
)
.
primary_key
:
if
to_field
and
not
relation_info
.
re
verse
and
not
relation_info
.
re
lated_model
.
_meta
.
get_field
(
to_field
)
.
primary_key
:
field_kwargs
[
'slug_field'
]
=
to_field
field_kwargs
[
'slug_field'
]
=
to_field
field_class
=
self
.
serializer_related_to_field
field_class
=
self
.
serializer_related_to_field
...
...
rest_framework/utils/field_mapping.py
View file @
8d0a91b0
...
@@ -238,7 +238,7 @@ def get_relation_kwargs(field_name, relation_info):
...
@@ -238,7 +238,7 @@ def get_relation_kwargs(field_name, relation_info):
"""
"""
Creates a default instance of a flat relational field.
Creates a default instance of a flat relational field.
"""
"""
model_field
,
related_model
,
to_many
,
to_field
,
has_through_model
=
relation_info
model_field
,
related_model
,
to_many
,
to_field
,
has_through_model
,
reverse
=
relation_info
kwargs
=
{
kwargs
=
{
'queryset'
:
related_model
.
_default_manager
,
'queryset'
:
related_model
.
_default_manager
,
'view_name'
:
get_detail_view_name
(
related_model
)
'view_name'
:
get_detail_view_name
(
related_model
)
...
...
rest_framework/utils/model_meta.py
View file @
8d0a91b0
...
@@ -23,7 +23,8 @@ RelationInfo = namedtuple('RelationInfo', [
...
@@ -23,7 +23,8 @@ RelationInfo = namedtuple('RelationInfo', [
'related_model'
,
'related_model'
,
'to_many'
,
'to_many'
,
'to_field'
,
'to_field'
,
'has_through_model'
'has_through_model'
,
'reverse'
])
])
...
@@ -81,7 +82,8 @@ def _get_forward_relationships(opts):
...
@@ -81,7 +82,8 @@ def _get_forward_relationships(opts):
related_model
=
get_related_model
(
field
),
related_model
=
get_related_model
(
field
),
to_many
=
False
,
to_many
=
False
,
to_field
=
_get_to_field
(
field
),
to_field
=
_get_to_field
(
field
),
has_through_model
=
False
has_through_model
=
False
,
reverse
=
False
)
)
# Deal with forward many-to-many relationships.
# Deal with forward many-to-many relationships.
...
@@ -94,7 +96,8 @@ def _get_forward_relationships(opts):
...
@@ -94,7 +96,8 @@ def _get_forward_relationships(opts):
to_field
=
None
,
to_field
=
None
,
has_through_model
=
(
has_through_model
=
(
not
get_remote_field
(
field
)
.
through
.
_meta
.
auto_created
not
get_remote_field
(
field
)
.
through
.
_meta
.
auto_created
)
),
reverse
=
False
)
)
return
forward_relations
return
forward_relations
...
@@ -118,7 +121,8 @@ def _get_reverse_relationships(opts):
...
@@ -118,7 +121,8 @@ def _get_reverse_relationships(opts):
related_model
=
related
,
related_model
=
related
,
to_many
=
get_remote_field
(
relation
.
field
)
.
multiple
,
to_many
=
get_remote_field
(
relation
.
field
)
.
multiple
,
to_field
=
_get_to_field
(
relation
.
field
),
to_field
=
_get_to_field
(
relation
.
field
),
has_through_model
=
False
has_through_model
=
False
,
reverse
=
True
)
)
# Deal with reverse many-to-many relationships.
# Deal with reverse many-to-many relationships.
...
@@ -135,7 +139,8 @@ def _get_reverse_relationships(opts):
...
@@ -135,7 +139,8 @@ def _get_reverse_relationships(opts):
has_through_model
=
(
has_through_model
=
(
(
getattr
(
get_remote_field
(
relation
.
field
),
'through'
,
None
)
is
not
None
)
and
(
getattr
(
get_remote_field
(
relation
.
field
),
'through'
,
None
)
is
not
None
)
and
not
get_remote_field
(
relation
.
field
)
.
through
.
_meta
.
auto_created
not
get_remote_field
(
relation
.
field
)
.
through
.
_meta
.
auto_created
)
),
reverse
=
True
)
)
return
reverse_relations
return
reverse_relations
...
...
tests/test_model_serializer.py
View file @
8d0a91b0
...
@@ -89,6 +89,15 @@ class ChoicesModel(models.Model):
...
@@ -89,6 +89,15 @@ class ChoicesModel(models.Model):
choices_field_with_nonstandard_args
=
models
.
DecimalField
(
max_digits
=
3
,
decimal_places
=
1
,
choices
=
DECIMAL_CHOICES
,
verbose_name
=
'A label'
)
choices_field_with_nonstandard_args
=
models
.
DecimalField
(
max_digits
=
3
,
decimal_places
=
1
,
choices
=
DECIMAL_CHOICES
,
verbose_name
=
'A label'
)
class
Issue3674ParentModel
(
models
.
Model
):
title
=
models
.
CharField
(
max_length
=
64
)
class
Issue3674ChildModel
(
models
.
Model
):
parent
=
models
.
ForeignKey
(
Issue3674ParentModel
,
related_name
=
'children'
)
value
=
models
.
CharField
(
primary_key
=
True
,
max_length
=
64
)
class
TestModelSerializer
(
TestCase
):
class
TestModelSerializer
(
TestCase
):
def
test_create_method
(
self
):
def
test_create_method
(
self
):
class
TestSerializer
(
serializers
.
ModelSerializer
):
class
TestSerializer
(
serializers
.
ModelSerializer
):
...
@@ -996,3 +1005,62 @@ class TestUniquenessOverride(TestCase):
...
@@ -996,3 +1005,62 @@ class TestUniquenessOverride(TestCase):
fields
=
TestSerializer
()
.
fields
fields
=
TestSerializer
()
.
fields
self
.
assertFalse
(
fields
[
'field_1'
]
.
required
)
self
.
assertFalse
(
fields
[
'field_1'
]
.
required
)
self
.
assertTrue
(
fields
[
'field_2'
]
.
required
)
self
.
assertTrue
(
fields
[
'field_2'
]
.
required
)
class
Issue3674Test
(
TestCase
):
def
test_nonPK_foreignkey_model_serializer
(
self
):
class
TestParentModel
(
models
.
Model
):
title
=
models
.
CharField
(
max_length
=
64
)
class
TestChildModel
(
models
.
Model
):
parent
=
models
.
ForeignKey
(
TestParentModel
,
related_name
=
'children'
)
value
=
models
.
CharField
(
primary_key
=
True
,
max_length
=
64
)
class
TestChildModelSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
TestChildModel
fields
=
(
'value'
,
'parent'
)
class
TestParentModelSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
TestParentModel
fields
=
(
'id'
,
'title'
,
'children'
)
parent_expected
=
dedent
(
"""
TestParentModelSerializer():
id = IntegerField(label='ID', read_only=True)
title = CharField(max_length=64)
children = PrimaryKeyRelatedField(many=True, queryset=TestChildModel.objects.all())
"""
)
self
.
assertEqual
(
unicode_repr
(
TestParentModelSerializer
()),
parent_expected
)
child_expected
=
dedent
(
"""
TestChildModelSerializer():
value = CharField(max_length=64, validators=[<UniqueValidator(queryset=TestChildModel.objects.all())>])
parent = PrimaryKeyRelatedField(queryset=TestParentModel.objects.all())
"""
)
self
.
assertEqual
(
unicode_repr
(
TestChildModelSerializer
()),
child_expected
)
def
test_nonID_PK_foreignkey_model_serializer
(
self
):
class
TestChildModelSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
Issue3674ChildModel
fields
=
(
'value'
,
'parent'
)
class
TestParentModelSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
Issue3674ParentModel
fields
=
(
'id'
,
'title'
,
'children'
)
parent
=
Issue3674ParentModel
.
objects
.
create
(
title
=
'abc'
)
child
=
Issue3674ChildModel
.
objects
.
create
(
value
=
'def'
,
parent
=
parent
)
parent_serializer
=
TestParentModelSerializer
(
parent
)
child_serializer
=
TestChildModelSerializer
(
child
)
parent_expected
=
{
'children'
:
[
'def'
],
'id'
:
1
,
'title'
:
'abc'
}
self
.
assertEqual
(
parent_serializer
.
data
,
parent_expected
)
child_expected
=
{
'parent'
:
1
,
'value'
:
'def'
}
self
.
assertEqual
(
child_serializer
.
data
,
child_expected
)
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