This commit is contained in:
Rob Golding 2018-01-31 13:28:33 +00:00 committed by GitHub
commit dda054fea4
3 changed files with 28 additions and 8 deletions

View File

@ -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

View File

@ -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):

View File

@ -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