[英]DRF queryset to return specific field
我正在使用這種結構創建一個 django rest 框架應用程序(假設導入是正確的,所以我從下面的代碼中省略了它們。
模型.py:
class Door(models.Model):
type = models.CharField(max_length=40)
color = models.CharField(max_length=40)
序列化程序.py:
class DoorSerializer(serializers.ModelSerializer):
class Meta:
model = Door
fields = ['type', 'color']
視圖.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
到目前為止,這符合預期,當我對localhost/Doors
進行 api 調用時,它會列出所有門。 當我對localhost/Doors/?type=big
進行 api 調用時,它會列出在其“類型”字段中具有“大”值的所有門。
我想做的補充是另一個參數檢查,它將返回數據庫中存在的所有唯一門類型的列表。 這可以通過使用以下方法在 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=whatever
時,這將返回與Door.objects.all().values('type').distinct()
相同的結果
但是我收到錯誤消息:“嘗試獲取序列化程序 DoorSerializer 上的字段color
值時DoorSerializer
。\n序列化程序字段可能命名不正確,並且與dict
實例上的任何屬性或鍵都不匹配。\n原始異常文本為:'顏色'。”
我假設這意味着序列化程序需要一個 object 或包含相應 model 的所有字段的對象列表。
有什么方法可以通過修復視圖來規避這個問題,還是應該創建一個不同的序列化程序? 無論哪種情況,由於我對 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 返回給我列表{"big", "small}
from rest_framework.decorators import api_view
from rest_framework.response import Response
@api_view()
def Unique_door_types(request):
types = Door.objects.values_list('type', flat=True).distinct()
return Response({"types": list(types)})
無需額外的視圖或序列化程序。 覆蓋list
方法。 請注意,這更像是一種技巧,而不是一種好的編程方式。
from rest_framework.response import Response
class DoorViewSet(viewsets.ModelViewSet):
serializer_class = DoorSerializer
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
def list(self, request):
unique = self.request.query_params.get('unique', '')
if unique:
types = Door.objects.values_list('type', flat=True).distinct()
return Response({"types": list(types)})
return super().list()
我的建議是創建一個單獨的路線,例如/doors/types/
。 為此,您可以使用@action
裝飾器向DoorViewSet
class 添加一個方法。 有關如何執行此操作的更多詳細信息,請參閱https://www.django-rest-framework.org/api-guide/viewsets/#marking-extra-actions-for-routing 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.