mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-03 12:00:12 +03:00
Merge 130b83623e
into 2fa04caf7c
This commit is contained in:
commit
dda054fea4
|
@ -20,7 +20,7 @@ from collections import Mapping, OrderedDict
|
||||||
from django.core.exceptions import ValidationError as DjangoValidationError
|
from django.core.exceptions import ValidationError as DjangoValidationError
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import DurationField as ModelDurationField
|
from django.db.models import manager, DurationField as ModelDurationField
|
||||||
from django.db.models.fields import Field as DjangoModelField
|
from django.db.models.fields import Field as DjangoModelField
|
||||||
from django.db.models.fields import FieldDoesNotExist
|
from django.db.models.fields import FieldDoesNotExist
|
||||||
from django.utils import six, timezone
|
from django.utils import six, timezone
|
||||||
|
@ -654,7 +654,7 @@ class ListSerializer(BaseSerializer):
|
||||||
"""
|
"""
|
||||||
# Dealing with nested relationships, data can be a Manager,
|
# Dealing with nested relationships, data can be a Manager,
|
||||||
# so, first get a queryset from the Manager if needed
|
# so, first get a queryset from the Manager if needed
|
||||||
iterable = data.all() if isinstance(data, models.Manager) else data
|
iterable = data.all() if isinstance(data, manager.BaseManager) else data
|
||||||
|
|
||||||
return [
|
return [
|
||||||
self.child.to_representation(item) for item in iterable
|
self.child.to_representation(item) for item in iterable
|
||||||
|
|
|
@ -3,6 +3,8 @@ from __future__ import unicode_literals
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.db.models.manager import BaseManager
|
||||||
|
from django.db.models.query import QuerySet
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,12 +47,18 @@ class UUIDForeignKeyTarget(RESTFrameworkModel):
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100)
|
||||||
|
|
||||||
|
|
||||||
|
class ForeignKeySourceManager(BaseManager.from_queryset(QuerySet)):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ForeignKeySource(RESTFrameworkModel):
|
class ForeignKeySource(RESTFrameworkModel):
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100)
|
||||||
target = models.ForeignKey(ForeignKeyTarget, related_name='sources',
|
target = models.ForeignKey(ForeignKeyTarget, related_name='sources',
|
||||||
help_text='Target', verbose_name='Target',
|
help_text='Target', verbose_name='Target',
|
||||||
on_delete=models.CASCADE)
|
on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
objects = ForeignKeySourceManager()
|
||||||
|
|
||||||
|
|
||||||
# Nullable ForeignKey
|
# Nullable ForeignKey
|
||||||
class NullableForeignKeySource(RESTFrameworkModel):
|
class NullableForeignKeySource(RESTFrameworkModel):
|
||||||
|
|
|
@ -26,16 +26,24 @@ class ManyToManySourceSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
|
||||||
# ForeignKey
|
# ForeignKey
|
||||||
|
class ForeignKeySourceSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = ForeignKeySource
|
||||||
|
fields = ('id', 'name', 'target')
|
||||||
|
|
||||||
|
|
||||||
class ForeignKeyTargetSerializer(serializers.ModelSerializer):
|
class ForeignKeyTargetSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ForeignKeyTarget
|
model = ForeignKeyTarget
|
||||||
fields = ('id', 'name', 'sources')
|
fields = ('id', 'name', 'sources')
|
||||||
|
|
||||||
|
|
||||||
class ForeignKeySourceSerializer(serializers.ModelSerializer):
|
class ForeignKeyTargetWithSourcesSerializer(serializers.ModelSerializer):
|
||||||
|
sources = ForeignKeySourceSerializer(many=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ForeignKeySource
|
model = ForeignKeyTarget
|
||||||
fields = ('id', 'name', 'target')
|
fields = ('id', 'name', 'sources')
|
||||||
|
|
||||||
|
|
||||||
# Nullable ForeignKey
|
# Nullable ForeignKey
|
||||||
|
@ -219,9 +227,13 @@ class PKForeignKeyTests(TestCase):
|
||||||
|
|
||||||
def test_reverse_foreign_key_retrieve(self):
|
def test_reverse_foreign_key_retrieve(self):
|
||||||
queryset = ForeignKeyTarget.objects.all()
|
queryset = ForeignKeyTarget.objects.all()
|
||||||
serializer = ForeignKeyTargetSerializer(queryset, many=True)
|
serializer = ForeignKeyTargetWithSourcesSerializer(queryset, many=True)
|
||||||
expected = [
|
expected = [
|
||||||
{'id': 1, 'name': 'target-1', 'sources': [1, 2, 3]},
|
{'id': 1, 'name': 'target-1', 'sources': [
|
||||||
|
{'id': 1, 'name': 'source-1', 'target': 1},
|
||||||
|
{'id': 2, 'name': 'source-2', 'target': 1},
|
||||||
|
{'id': 3, 'name': 'source-3', 'target': 1},
|
||||||
|
]},
|
||||||
{'id': 2, 'name': 'target-2', 'sources': []},
|
{'id': 2, 'name': 'target-2', 'sources': []},
|
||||||
]
|
]
|
||||||
with self.assertNumQueries(3):
|
with self.assertNumQueries(3):
|
||||||
|
@ -229,7 +241,7 @@ class PKForeignKeyTests(TestCase):
|
||||||
|
|
||||||
def test_reverse_foreign_key_retrieve_prefetch_related(self):
|
def test_reverse_foreign_key_retrieve_prefetch_related(self):
|
||||||
queryset = ForeignKeyTarget.objects.all().prefetch_related('sources')
|
queryset = ForeignKeyTarget.objects.all().prefetch_related('sources')
|
||||||
serializer = ForeignKeyTargetSerializer(queryset, many=True)
|
serializer = ForeignKeyTargetWithSourcesSerializer(queryset, many=True)
|
||||||
with self.assertNumQueries(2):
|
with self.assertNumQueries(2):
|
||||||
serializer.data
|
serializer.data
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user