Python DRF queryset返回特定字段
我正在用这种结构创建一个django rest框架应用程序(假设导入是正确的,所以我在下面的代码中省略了它们) models.py: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
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,如果存在,则发送自定义响应。两者都非常完美,它们可以正常工作,并且完全符合我的要求!非常感谢您花时间帮助我:)不客气。:)如果我能正确理解,如果您得到的是唯一的查询参数,您想返回所有可能值的列表吗?这是正确的,特定变量的所有可能值我已经收到了令人满意的解决方案,并且能够继续我的项目。不过,您的答案是相关和正确的,谢谢您的支持答复:)