Use the str representation of a queryset instead of the __repr__

This way, if the serializer is inadvertently converted to a string, the
queryset won't be executed.
This commit is contained in:
Michel Sabchuk 2021-03-06 13:21:47 -03:00
parent ec29ff8a80
commit 2ff4974045
2 changed files with 20 additions and 1 deletions

View File

@ -23,10 +23,17 @@ def manager_repr(value):
return repr(value)
def queryset_repr(queryset):
return "{}".format(queryset.query)
def smart_repr(value):
if isinstance(value, models.Manager):
return manager_repr(value)
if isinstance(value, models.QuerySet):
value = queryset_repr(value)
if isinstance(value, Promise) and value._delegate_text:
value = force_str(value)

View File

@ -23,7 +23,7 @@ from django.db.models.signals import m2m_changed
from django.dispatch import receiver
from django.test import TestCase
from rest_framework import serializers
from rest_framework import serializers, fields
from rest_framework.compat import postgres_fields
from .models import NestedForeignKeySource
@ -559,6 +559,18 @@ class TestRelationalFieldMappings(TestCase):
""")
self.assertEqual(repr(TestSerializer()), expected)
def test_manual_pk_relation_will_customize_queryset_repr_to_avoid_execute_it(self):
queryset = ForeignKeyTargetModel.objects.all()
class TestSerializer(serializers.Serializer):
field = serializers.PrimaryKeyRelatedField(queryset=queryset)
expected = dedent("""
TestSerializer():
field = PrimaryKeyRelatedField(queryset='{}')
""")
self.assertEqual(repr(TestSerializer()), expected.format(queryset.query))
def test_nested_relations(self):
class TestSerializer(serializers.ModelSerializer):
class Meta: