Fixes instance check in ListSerializer.to_representation (#8726) (#8727)

* Fixes 'RelatedManager' object is not iterable in ListSerializer.to_representation.(#8726)

* Change to only BaseManager

* Commit unit test

* Update tests/test_serializer_lists.py

* Update tests/test_serializer_lists.py

* Update tests/test_serializer_lists.py

* Update tests/test_serializer_lists.py

* Update tests/test_serializer_lists.py

* Update tests/test_serializer_lists.py

* Format import

* Format import

Co-authored-by: Asif Saif Uddin <auvipy@gmail.com>
This commit is contained in:
954 2022-11-22 14:01:01 +08:00 committed by GitHub
parent 9e56f54efb
commit 03c2ef1787
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 1 deletions

View File

@ -683,7 +683,7 @@ class ListSerializer(BaseSerializer):
"""
# Dealing with nested relationships, data can be a Manager,
# 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, models.manager.BaseManager) else data
return [
self.child.to_representation(item) for item in iterable

View File

@ -2,6 +2,8 @@ import uuid
from django.contrib.auth.models import User
from django.db import models
from django.db.models import QuerySet
from django.db.models.manager import BaseManager
from django.utils.translation import gettext_lazy as _
@ -124,3 +126,27 @@ class OneToOnePKSource(RESTFrameworkModel):
target = models.OneToOneField(
OneToOneTarget, primary_key=True,
related_name='required_source', on_delete=models.CASCADE)
class CustomManagerModel(RESTFrameworkModel):
class CustomManager:
def __new__(cls, *args, **kwargs):
cls = BaseManager.from_queryset(
QuerySet
)
return cls
objects = CustomManager()()
# `CustomManager()` will return a `BaseManager` class.
# We need to instantiation it, so we write `CustomManager()()` here.
text = models.CharField(
max_length=100,
verbose_name=_("Text comes here"),
help_text=_("Text description.")
)
o2o_target = models.ForeignKey(OneToOneTarget,
help_text='OneToOneTarget',
verbose_name='OneToOneTarget',
on_delete=models.CASCADE)

View File

@ -6,6 +6,9 @@ from django.utils.datastructures import MultiValueDict
from rest_framework import serializers
from rest_framework.exceptions import ErrorDetail
from tests.models import (
CustomManagerModel, NullableOneToOneSource, OneToOneTarget
)
class BasicObject:
@ -683,3 +686,43 @@ class TestMaxMinLengthListSerializer:
assert min_serializer.validated_data == input_data
assert not max_min_serializer.is_valid()
@pytest.mark.django_db()
class TestToRepresentationManagerCheck:
"""
https://github.com/encode/django-rest-framework/issues/8726
"""
def setup_method(self):
class CustomManagerModelSerializer(serializers.ModelSerializer):
class Meta:
model = CustomManagerModel
fields = '__all__'
class OneToOneTargetSerializer(serializers.ModelSerializer):
my_model = CustomManagerModelSerializer(many=True, source="custommanagermodel_set")
class Meta:
model = OneToOneTarget
fields = '__all__'
depth = 3
class NullableOneToOneSourceSerializer(serializers.ModelSerializer):
target = OneToOneTargetSerializer()
class Meta:
model = NullableOneToOneSource
fields = '__all__'
self.serializer = NullableOneToOneSourceSerializer
def test(self):
o2o_target = OneToOneTarget.objects.create(name='OneToOneTarget')
NullableOneToOneSource.objects.create(
name='NullableOneToOneSource',
target=o2o_target
)
queryset = NullableOneToOneSource.objects.all()
serializer = self.serializer(queryset, many=True)
assert serializer.data