Python DRF queryset返回特定字段

Python DRF queryset返回特定字段,python,django,django-rest-framework,Python,Django,Django Rest Framework,我正在用这种结构创建一个django rest框架应用程序(假设导入是正确的,所以我在下面的代码中省略了它们) models.py: class Door(models.Model): type = models.CharField(max_length=40) color = models.CharField(max_length=40) serializers.py: class DoorSerializer(serializers.ModelSerializer): clas

我正在用这种结构创建一个django rest框架应用程序(假设导入是正确的,所以我在下面的代码中省略了它们)

models.py:

class Door(models.Model):
  type = models.CharField(max_length=40)
  color = models.CharField(max_length=40)
serializers.py:

class DoorSerializer(serializers.ModelSerializer):
  class Meta:
    model = Door
    fields = ['type', 'color']
views.py:

class DoorViewSet(viewsets.ModelViewSet):
  serializer_class = DoorSerializer
  queryset = Door.objects.all()
  def get_queryset(self, *args, **kwargs):
    queryset = Door.objects.all()
    parameter = self.request.query_params.get('type', '')
    if parameter:
      return queryset.filter(type=parameter)
    else:
      return queryset
...
parameter = self.request.query.params.get('type', '')
unique = self.request.query.params.get('unique', '')
if parameter:
  ...
elif unique:
  return Door.objects.all().values('type').distinct()
...
到目前为止,当我对
localhost/Doors
进行api调用时,它会列出所有的门。当我对
localhost/Doors/?type=big
进行api调用时,它会列出在其“type”字段中具有值“big”的所有门

我想添加的是另一个参数检查,它将返回数据库中存在的所有唯一门类型的列表。这可以在manage.py shell中通过使用:
door.objects.all().values('type').distinct()实现

我尝试对views.py进行以下修改:

...
parameter = self.request.query.params.get('type', '')
unique = self.request.query.params.get('unique', '')
if parameter:
  ...
elif unique:
  return Door.objects.all().values('type').distinct()
...
我的假设是,当我调用
localhost/Doors/?unique=which

但是我得到了错误:“get-KeyError在尝试获取序列化程序
DoorSerializer
上的字段
color
的值时出错\n序列化程序字段的名称可能不正确,并且与
dict
实例上的任何属性或键都不匹配。\n原始异常文本是:'color'。”

我假设这意味着序列化程序需要一个对象或对象列表,其中包含相应模型的所有字段

有没有什么办法可以通过修复视图来避免这种情况,或者我应该创建一个不同的序列化程序?在这两种情况下,由于我对DRF/django的差异感到非常困惑,而且我可能无法遵循抽象指令,您能提供一个代码解决方案来解决这个问题吗?同样,在非常可能的情况下我的假设完全错误,你能解释一下是什么导致了这个问题吗?谢谢你抽出时间

编辑以澄清所需结果:

假设我的数据库有4个门,它们是:

{
  "id": 1,
  "type": "big",
  "color": "blue"
},
{
  "id": 2,
  "type": "big",
  "color": "yellow"
},
{
  "id": 3,
  "type": "small",
  "color": "green"
},
{
  "id": 4,
  "type": "big",
  "color": "red"
},
我想对某个url发出
get
请求,例如
localhost/Doors/?unique=Yes
,并让api将列表返回给我
{“大”、“小”}

  • 编写自己的视图:返回类型列表的短视图。您需要在此处设置一个新路径。我个人会选择此选项,因为您期望的响应与视图的其他部分不同
  • 从rest\u framework.decorators导入api\u视图
    来自rest\u framework.response导入响应
    @api_视图()
    def唯一车门类型(请求):
    types=Door.objects.values\u list('type',flat=True).distinct()
    返回响应({“类型”:列表(类型)})
    
  • 没有附加视图:
  • 不需要额外的视图或序列化程序。重写
    list
    方法。请注意,这更接近于一种技巧,而不是一种好的编程方法

    来自rest\u framework.response导入响应
    类别DoorViewSet(viewsets.ModelViewSet):
    序列化程序\u类=门序列化程序
    def get_queryset(self、*args、**kwargs):
    queryset=Door.objects.all()
    参数=self.request.query_params.get('type','')
    如果参数:
    返回queryset.filter(类型=参数)
    其他:
    返回查询集
    def列表(自我、请求):
    unique=self.request.query_params.get('unique','')
    如果是唯一的:
    types=Door.objects.values\u list('type',flat=True).distinct()
    返回响应({“类型”:列表(类型)})
    返回super().list()
    
    我的建议是创建一个单独的路由,如
    /doors/types/
    。您可以通过使用
    @action
    装饰器向
    DoorViewSet
    类添加一个方法来实现此目的。有关如何实现此目的的更多详细信息,请参阅。

    谢谢您的回答。我恐怕无法理解此代码的功能,只需添加它即可o我的应用程序无法运行。我正在更新我的问题,以清楚起见,以防我被误解。关于如何创建一个简单的函数视图的简短代码将是完美的,如果您能够提供,这正是我所需要的。感谢您的回答!我用两个命题进行了编辑。第二个命题可能更接近您的预期oes不需要额外的视图,因此也不需要额外的路径。它会检查是否存在唯一的keywork,如果存在,则发送自定义响应。两者都非常完美,它们可以正常工作,并且完全符合我的要求!非常感谢您花时间帮助我:)不客气。:)如果我能正确理解,如果您得到的是唯一的查询参数,您想返回所有可能值的列表吗?这是正确的,特定变量的所有可能值我已经收到了令人满意的解决方案,并且能够继续我的项目。不过,您的答案是相关和正确的,谢谢您的支持答复:)