Django DRF ViewSet返回带有空值的QuerySet

Django DRF ViewSet返回带有空值的QuerySet,django,django-rest-framework,django-rest-viewsets,drf-queryset,Django,Django Rest Framework,Django Rest Viewsets,Drf Queryset,我在查询生成器中使用了一个名为“QueryCriteriaViewSet”的DRF视图集,它允许用户选择一个字段,然后从相关条件中进行选择。因此,例如,用户可以选择“注册状态”字段,然后从“活动”和“非活动”的相关标准中进行选择 当我从主“person”模型中选择一个字段时,这完全可以正常工作。但是,当我从相关模型(如“lookup\u party”模型)中选择字段时,会遇到问题。但奇怪的是,当我将queryset打印到控制台时,它工作得很好,但当我调用API时,它返回一个空对象列表 再举一个例

我在查询生成器中使用了一个名为“QueryCriteriaViewSet”的DRF视图集,它允许用户选择一个字段,然后从相关条件中进行选择。因此,例如,用户可以选择“注册状态”字段,然后从“活动”和“非活动”的相关标准中进行选择

当我从主“person”模型中选择一个字段时,这完全可以正常工作。但是,当我从相关模型(如“lookup\u party”模型)中选择字段时,会遇到问题。但奇怪的是,当我将queryset打印到控制台时,它工作得很好,但当我调用API时,它返回一个空对象列表

再举一个例子,下面是我打电话时发生的情况:

api/querycriteria/?fields=reg\u status
返回:

[
    {"reg_status": "Active"}, 
    {"reg_status": "Inactive"}
]
[
    {},
    {},
    {},
    {},
    {}
]
api/querycriteria/?fields=party\u party\u name
返回:

[
    {"reg_status": "Active"}, 
    {"reg_status": "Inactive"}
]
[
    {},
    {},
    {},
    {},
    {}
]
即使在返回查询集之前打印(查询集)时,也会打印以下内容:

<QuerySet [{'party__party_name': None}, {'party__party_name': 'Democratic'}, 
{'party__party_name': 'Non-Partisan'}, {'party__party_name': 'Registered 
Independent'}, {'party__party_name': 'Republican'}]>
如果有任何其他信息会有所帮助,请告诉我

这是我的序列化程序:

from django.contrib.auth import get_user_model
from rest_framework import serializers
from rest_framework.reverse import reverse
from ..models.people import Person
from ..models.people_emails import Email
from ..models.people_addresses import Address
from ..models.people_phones import Phone
from ..models.people_tags import PersonTag
from ..models.people_elections import PersonElection
from ..models.people_districts import PersonDistrict
from ..models.people_attributes import Attribute
from .serializer_dynamic_fields import DynamicFieldsModelSerializer
from .serializer_tag import TagSerializer
from .serializer_email import EmailSerializer
from .serializer_address import AddressSerializer
from .serializer_phone import PhoneSerializer
from .serializer_election import ElectionSerializer
from .serializer_attribute import AttributeSerializer
from .serializer_district import DistrictSerializer

class QueryCriteriaSerializer(DynamicFieldsModelSerializer):

    emails = EmailSerializer(many=True, required=False)
    addresses = AddressSerializer(many=True, required=False)
    phones = PhoneSerializer(many=True, required=False)
    tags = TagSerializer(many=True, required=False)
    elections = ElectionSerializer(many=True, required=False)
    attributes = AttributeSerializer(many=True, required=False)
    districts = DistrictSerializer(many=True, required=False)

    class Meta:
        model = Person
        fields = ('id', 'elected_official', 'title', 'first', 'last', 'middle',    'suffix',
        'full_name', 'birthdate', 'sex', 'website', 'deceased', 'registered',    'party',
        'reg_date', 'reg_status', 'reg_state', 'county', 'match_id',
        'date_added', 'date_updated', 'do_not_call', 'do_not_mail',    'do_not_email', 'do_not_text', 'emails',
        'addresses', 'phones', 'tags', 'attributes', 'elections', 'districts')
from django.contrib.auth import get_user_model
from rest_framework import serializers

class DynamicFieldsModelSerializer(serializers.ModelSerializer):
    """
    A ModelSerializer that takes an additional `fields` argument that
    controls which fields should be displayed.
    """

    def __init__(self, *args, **kwargs):
        # Don't pass the 'fields' arg up to the superclass
        fields = kwargs.pop('fields', None)

        # Instantiate the superclass normally
        super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        if fields is not None:
            # Drop any fields that are not specified in the `fields` argument.
            allowed = set(fields)
            existing = set(self.fields)
            for field_name in existing - allowed:
                self.fields.pop(field_name)
这是DynamicFieldsModelSerializer:

from django.contrib.auth import get_user_model
from rest_framework import serializers
from rest_framework.reverse import reverse
from ..models.people import Person
from ..models.people_emails import Email
from ..models.people_addresses import Address
from ..models.people_phones import Phone
from ..models.people_tags import PersonTag
from ..models.people_elections import PersonElection
from ..models.people_districts import PersonDistrict
from ..models.people_attributes import Attribute
from .serializer_dynamic_fields import DynamicFieldsModelSerializer
from .serializer_tag import TagSerializer
from .serializer_email import EmailSerializer
from .serializer_address import AddressSerializer
from .serializer_phone import PhoneSerializer
from .serializer_election import ElectionSerializer
from .serializer_attribute import AttributeSerializer
from .serializer_district import DistrictSerializer

class QueryCriteriaSerializer(DynamicFieldsModelSerializer):

    emails = EmailSerializer(many=True, required=False)
    addresses = AddressSerializer(many=True, required=False)
    phones = PhoneSerializer(many=True, required=False)
    tags = TagSerializer(many=True, required=False)
    elections = ElectionSerializer(many=True, required=False)
    attributes = AttributeSerializer(many=True, required=False)
    districts = DistrictSerializer(many=True, required=False)

    class Meta:
        model = Person
        fields = ('id', 'elected_official', 'title', 'first', 'last', 'middle',    'suffix',
        'full_name', 'birthdate', 'sex', 'website', 'deceased', 'registered',    'party',
        'reg_date', 'reg_status', 'reg_state', 'county', 'match_id',
        'date_added', 'date_updated', 'do_not_call', 'do_not_mail',    'do_not_email', 'do_not_text', 'emails',
        'addresses', 'phones', 'tags', 'attributes', 'elections', 'districts')
from django.contrib.auth import get_user_model
from rest_framework import serializers

class DynamicFieldsModelSerializer(serializers.ModelSerializer):
    """
    A ModelSerializer that takes an additional `fields` argument that
    controls which fields should be displayed.
    """

    def __init__(self, *args, **kwargs):
        # Don't pass the 'fields' arg up to the superclass
        fields = kwargs.pop('fields', None)

        # Instantiate the superclass normally
        super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        if fields is not None:
            # Drop any fields that are not specified in the `fields` argument.
            allowed = set(fields)
            existing = set(self.fields)
            for field_name in existing - allowed:
                self.fields.pop(field_name)

好了,现在发现问题了,只有当传递给DynamicFieldsModelSerializer的字段是序列化程序原始字段的子集时,DynamicFieldsModelSerializer才起作用

您应该以接受额外字段的方式使用序列化程序,如下所示:

class ExtraDynamicFieldsModelSerializer(serializers.ModelSerializer):


    def __init__(self, *args, **kwargs):
        extra_fields = kwargs.pop('fields', [])
        self.extra_fields = set()
        # Instantiate the superclass normally
        super(ExtraDynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        allowed = set(extra_fields)
        existing = set(self.fields)
        for field_name in existing - allowed:
            self.fields.pop(field_name)

        for field_name in allowed - existing:
            self.extra_fields.add(field_name)



    def to_representation(self, obj):
        data = super().to_representation(obj)
        for field in self.extra_fields:
            data[field] = obj[field]
        return data

我觉得你的连载器有问题,请把它带到你的question@changak刚刚在我的序列化中添加了请也添加DynamicFieldsModelSerializer,我认为只有当字段是您的serializer@changak,谢谢,刚刚用DynamicFieldsModelSerializerI更新了我的答案。让我知道它是否有效。谢谢@changak。它不太管用(但我觉得很接近)。你能再解释一下def to_表示法(self,obj)在做什么吗?刚刚更新了我的答案,问题出在init函数中,to_表示法是序列化程序调用的函数,用于将实例更改为具有原始数据类型的dict。同样在to_表示法中,它将从对象中获取所有字段的值,我们将它们放入额外的字段中,并将它们添加到返回的数据中。谢谢!我不得不换一行,但现在这行了。出于某种原因,
data[field]=getattr(obj,field,”)
返回了空值(它没有将“field”识别为属性。但是当我将该行更改为
data[field]=obj[field]时
它是有效的!如果你知道为什么会出现这种情况,我很想进一步了解它,但很高兴问题得到解决!谢谢,我会更新我的答案,我认为是.values()造成的,否则queryset将返回模型实例列表,但现在它将返回DICT列表。