[英]DRF: Method GET return objects based on parameter
我正在學習Django,並且我正在嘗試構建一個端點,該端點根據URL中給出的參數返回對象。
目前我有這些URL:
/api/v1/
作為root返回:
GET /api/v1/
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"device-groups": "http://127.0.0.1:8000/api/v1/device-groups/"
}
/api/v1/device-groups/
返回所有設備組:
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"device_group_name": "Default",
"group_uuid": "7465febe-7c46-4420-85a1-73dfe0af812c",
"color": "4286f4",
"is_default": true,
"customer": {
"customer_name": "Customer1",
"customer_uuid": "b3eb5d7d-d1a8-4997-a65b-28bed71b7cc6"
}
},
{
"device_group_name": "Default",
"group_uuid": "e12d02d0-7916-477e-b318-9680a38617db",
"color": "4286f4",
"is_default": true,
"customer": {
"customer_name": "Another customer",
"customer_uuid": "5b5dafab-c311-4f58-80f5-c50d77fcf8a5"
}
},
{
"device_group_name": "group of customer1",
"group_uuid": "c72e87b1-e7c8-4dcd-a9c7-4f6a016d7676",
"color": "#ffffff",
"is_default": false,
"customer": {
"customer_name": "Customer1",
"customer_uuid": "b3eb5d7d-d1a8-4997-a65b-28bed71b7cc6"
}
}
]
我想要一個像/api/v1/device-groups/<customer_uuid>/
這樣的端點,它返回與給定customer_uuid相關的設備組。
我的serializers.py
:
class CustomerSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Customer
fields = ('customer_name', 'customer_uuid')
class DeviceGroupSerializer(serializers.HyperlinkedModelSerializer):
customer = CustomerSerializer(many=False, read_only=True)
class Meta:
model = DeviceGroup
fields = ('device_group_name', 'group_uuid', 'color', 'is_default', 'customer')
我的views.py
:
class DeviceGroupViewSet(viewsets.ModelViewSet):
serializer_class = DeviceGroupSerializer
queryset = DeviceGroup.objects.all()
我的urls.py
:
router = routers.DefaultRouter()
router.register(r'device-groups', views.DeviceGroupViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include(router.urls)),
]
我嘗試像這樣覆蓋get_queryset
:
def get_queryset(self):
customer = self.request.GET['customer']
queryset = DeviceGroup.objects.filter(customer=customer)
return queryset
但它導致: AssertionError: basename argument not specified, and could not automatically determine the name from the viewset, as it does not have a .queryset attribute.
我需要更改以獲取/api/v1/device-groups/<customer_uuid>/
endpoint,它只顯示與給定customer_uuid相關的設備組?
編輯
Internal Server Error: /api/v1/device-groups/
Traceback (most recent call last):
File "C:\Users\Stevy\PycharmProjects\tapartisan-api\env\lib\site-
packages\django\utils\datastructures.py", line 77, in __getitem__
list_ = super().__getitem__(key)
KeyError: 'customer'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Stevy\PycharmProjects\tapartisan-api\env\lib\site-
packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\Stevy\PycharmProjects\tapartisan-api\env\lib\site-
packages\django\core\handlers\base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Stevy\PycharmProjects\tapartisan-api\env\lib\site-
packages\django\core\handlers\base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Stevy\PycharmProjects\tapartisan-api\env\lib\site-
packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\Stevy\PycharmProjects\tapartisan-api\env\lib\site-
packages\rest_framework\viewsets.py", line 116, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Stevy\PycharmProjects\tapartisan-api\env\lib\site-
packages\rest_framework\views.py", line 495, in dispatch
response = self.handle_exception(exc)
File "C:\Users\Stevy\PycharmProjects\tapartisan-api\env\lib\site-
packages\rest_framework\views.py", line 455, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\Stevy\PycharmProjects\tapartisan-api\env\lib\site-
packages\rest_framework\views.py", line 492, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\Stevy\PycharmProjects\tapartisan-api\env\lib\site-
packages\rest_framework\mixins.py", line 40, in list
queryset = self.filter_queryset(self.get_queryset())
File "C:\Users\Stevy\PycharmProjects\tapartisan-api\app\core\views.py", line
13, in get_queryset
customer = self.request.GET['customer']
File "C:\Users\Stevy\PycharmProjects\tapartisan-api\env\lib\site-
packages\django\utils\datastructures.py", line 79, in __getitem__
raise MultiValueDictKeyError(key)
django.utils.datastructures.MultiValueDictKeyError: 'customer'`
路由器無法確定basename
。 您必須在路由器中定義基basename
。 像這樣
router.register(r'device-groups', views.DeviceGroupViewSet, base_name='device-groups')
base_name
實際上用於生成routes / url的名稱。 你可以在這里閱讀更多相關信息。
我不熟悉DRF,但一般來說,為了根據您必須參數獲取對象:
1)以這種方式定義你的url,記住你想要構建你的端點時動態輸入的customer_uuid所以,在regex的幫助下,你必須構建如下內容:
url(r'^/api/v1/device-groups/(?P<customer_uuid>\d+)/$', views.your_view, name='your_view')
正則表達式\\ d +將匹配任意大小的整數。 此整數將用於從數據庫中檢索Customer。 現在觀察我將正則表達式寫成(?P \\ d +),這告訴Django將值捕獲到名為customer_uuid的關鍵字參數中。
2)定義您的視圖功能
from django.shortcuts import render, get_object_or_404
from .models import Customer
def your_view(request, customer_uuid):
customer = get_object_or_404(Customer, pk=customer_uuid)
return render(request, 'customer.html', {'customer': customer})
希望能幫助到你
如果在視圖中定義不同的lookup_field,您應該得到您想要的內容,如:
class DeviceGroupViewSet(viewsets.ModelViewSet):
serializer_class = DeviceGroupSerializer
queryset = DeviceGroup.objects.all()
lookup_field = 'customer_uuid'
或者您可能希望查看本文檔以考慮不同的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.