簡體   English   中英

如何在不調用 API 的情況下從 DRF 中的 ModelViewSet 獲取數據

[英]How to get data from ModelViewSet in DRF without calling an API call

我將把我所有的 API 轉換為gRPC調用。 目前我能夠將所有ViewSet轉移到gRPC 中(示例代碼添加到這個問題的末尾)。 但是ModelViewSet ,它會出現這樣的錯誤。

Traceback (most recent call last):
  File "/home/wasdkiller/PycharmProjects/ocsa/dataengine-service/venv/lib/python3.6/site-packages/grpc/_server.py", line 435, in _call_behavior
    response_or_iterator = behavior(argument, context)
  File "/home/wasdkiller/PycharmProjects/ocsa/dataengine-service/servicers/tenant/main.py", line 15, in get_tenant
    data = ClientViewSet().list(request=original_request, )
  File "/home/wasdkiller/PycharmProjects/ocsa/dataengine-service/common/lib/decorators.py", line 128, in wrapper_format_response
    final_data = call_func(func, self, request, transaction, exception, *args, **kwargs)
  File "/home/wasdkiller/PycharmProjects/ocsa/dataengine-service/common/lib/decorators.py", line 99, in call_func
    return func(self, request, *args, **kwargs)
  File "/home/wasdkiller/PycharmProjects/ocsa/dataengine-service/api_v1/viewsets.py", line 471, in list
    data = super().list(request, *args, **kwargs).data
  File "/home/wasdkiller/PycharmProjects/ocsa/dataengine-service/venv/lib/python3.6/site-packages/rest_framework/mixins.py", line 38, in list
    queryset = self.filter_queryset(self.get_queryset())
  File "/home/wasdkiller/PycharmProjects/ocsa/dataengine-service/venv/lib/python3.6/site-packages/rest_framework/generics.py", line 158, in filter_queryset
    queryset = backend().filter_queryset(self.request, queryset, self)
AttributeError: 'ClientViewSet' object has no attribute 'request'

所以我的viewsets.py看起來像這樣( format_response裝飾器將其轉換為Response對象)

class ClientViewSet(viewsets.ModelViewSet):
    queryset = Client.objects.all()
    serializer_class = ser.ClientSerializer

    @format_response(exception=False)
    def list(self, request, *args, **kwargs):
        data = super().list(request, *args, **kwargs).data
        # data = {}
        return data, True, HTTPStatus.OK, 'data retrieve successfully'

當我將其稱為 API 時,它可以完美運行。 但我想在不調用 API 的情況下做同樣的事情。 這是我如何解決的,

from django.http import HttpRequest
from rest_framework.request import Request


# creating request object
django_request = HttpRequest()
django_request.method = 'GET'
drf_request = Request(django_request)

data = ClientViewSet().list(request=drf_request)
print(f'data: {data.data}')

ClientViewSet 中的super() ClientViewSet的問題,但是如果我取消注釋data = {}並注釋掉調用super() function,它適用於 ZDB974238714CA81434A7CE1D03 和上述方法。 I go through inside the DRF code base where error occurred, when calling the API the self object has the request object and above method it doesn't exist.

簡而言之,您需要在視圖集上調用as_view()和 map http 動詞,然后使用適當的 HttpRequest 調用 function。

django 中的所有視圖最終都是函數,DRF 是最重要的糖。 路由完成后,“ViewSet”以正常方式不存在,作為獨立的 class。

django_request = HttpRequest()
django_request.method = 'GET'

my_view = ClientViewSet.as_view({'get': 'list', 'post':'create'})
data = my_view(request=django_request)
print(f'data: {data.data}')

如果您想要詳細路線( users/37 ,...),那么您需要創建一個新視圖 function 映射到這些視圖集函數。 這不可能是同一個視圖 function 因為get現在需要在視圖集中指向不同的 function 而不是列表案例。 查看routers.py 源代碼了解發生了什么以及映射到哪里。

# map http 'get' to the 'retrive' function on the viewset
my_view = ClientViewSet.as_view({'get': 'retrieve', ...})

# pass in the kwarg the URL routing would normally extract
client_pk = 9329032 
data = my_view(request=django_request, pk=client_pk)

如果您想查看視圖集的所有映射是什么,那么您可以使用以下代碼段將它們打印出來:

router = SimpleRouter()
router.register("client", ClientViewSet, basename="client")
for url in router.urls:  # type: URLPattern
    print(f"{url.pattern} ==> {url.callback}")
    for verb, action in url.callback.actions.items():
        print(f"    {verb} -> {action}")

# output will be something like this
^client/$ ==> <function ClientViewSet at 0x11b91c280>
    get -> list
^client/(?P<pk>[^/.]+)/$ ==> <function ClientViewSet at 0x11b91c3a0>
    get -> retrieve
    put -> update
    patch -> partial_update
    delete -> destroy

你傳遞給這個視圖的kwargs將取決於你的 ViewSet 中的設置,比如lookup_url_kwarg ,但在大多數情況下它們會很簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM