mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 09:57:55 +03:00 
			
		
		
		
	* 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:
		
							parent
							
								
									9e56f54efb
								
							
						
					
					
						commit
						03c2ef1787
					
				| 
						 | 
					@ -683,7 +683,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, models.manager.BaseManager) else data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
            self.child.to_representation(item) for item in iterable
 | 
					            self.child.to_representation(item) for item in iterable
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,8 @@ import uuid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.contrib.auth.models import User
 | 
					from django.contrib.auth.models import User
 | 
				
			||||||
from django.db import models
 | 
					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 _
 | 
					from django.utils.translation import gettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,3 +126,27 @@ class OneToOnePKSource(RESTFrameworkModel):
 | 
				
			||||||
    target = models.OneToOneField(
 | 
					    target = models.OneToOneField(
 | 
				
			||||||
        OneToOneTarget, primary_key=True,
 | 
					        OneToOneTarget, primary_key=True,
 | 
				
			||||||
        related_name='required_source', on_delete=models.CASCADE)
 | 
					        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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,9 @@ from django.utils.datastructures import MultiValueDict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from rest_framework import serializers
 | 
					from rest_framework import serializers
 | 
				
			||||||
from rest_framework.exceptions import ErrorDetail
 | 
					from rest_framework.exceptions import ErrorDetail
 | 
				
			||||||
 | 
					from tests.models import (
 | 
				
			||||||
 | 
					    CustomManagerModel, NullableOneToOneSource, OneToOneTarget
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BasicObject:
 | 
					class BasicObject:
 | 
				
			||||||
| 
						 | 
					@ -683,3 +686,43 @@ class TestMaxMinLengthListSerializer:
 | 
				
			||||||
        assert min_serializer.validated_data == input_data
 | 
					        assert min_serializer.validated_data == input_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert not max_min_serializer.is_valid()
 | 
					        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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user