如何将url参数传递给APIRestFactory put请求?

2024-10-01 11:40:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经尝试了几个小时,但不知道如何通过APIRestFactory put请求传递url参数。我在运行服务器时通过Postman尝试过,url变量传递得很好,但当我在测试中运行它时,它就停止工作了

我的意思是,当我向“/litter/1/”发送邮递员PUT请求时,它将成功地将1作为变量litterId,因为我的url是这样设置的

path('litter/', include('apps.litter.urls')),

path('<int:litterId>/', LitterView.as_view(), name='litter-with-id')

但是,当我尝试向同一url发送APIRestFactory put请求时,由于某种原因,1将不再作为litterId

一些相关的代码

我的顶级url.py

from rest_framework.authtoken import views

from apps.litter.views import LitterView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('auth/', include('apps.my_auth.urls')),
    path('litter/', include('apps.litter.urls')),
]

这是我的应用程序特定URL.py

from .views import LitterView

urlpatterns = [
    path('', LitterView.as_view(), name='standard-litter'),
    path('<int:litterId>/', LitterView.as_view(), name='litter-with-id'),
]

这是我的观点

import json
  
from django.contrib.auth.models import User
from django.db import IntegrityError
from django.views.decorators.csrf import csrf_exempt
from rest_framework import authentication, permissions
from rest_framework.parsers import JSONParser
from rest_framework.permissions import IsAuthenticated
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
from django.db import models

from .models import Litter
from .serializers import LitterSerializer


#@csrf_exempt
class LitterView(APIView):
    """ 
    View for litter related requests

    * Requres token auth
    """
    permission_classes = (IsAuthenticated,)
    authentication_classes = [authentication.TokenAuthentication]
    renderer_classes = [JSONRenderer]

    def put(self, request, litterId=0):
        """
        Updates an old litter
        """

        try:
            litterModel = Litter.objects.get(user=request.user, id=litterId)
        except Litter.DoesNotExist:
            returnData = {'status': 'fail',
                          'error': 'Could not find object with that id.'}
            return Response(returnData)

        serializer_class = LitterSerializer
        serialized = LitterSerializer(litterModel, data=request.data)

        if serialized.is_valid():
            litterModel = serialized.save()

            returnData = {'status': 'okay',
                          'litter': [serialized.data]}
            return Response(returnData)
        else:
            return Response(serialized.errors, status=400)

这是相关的测试

def test_easy_successful_put_type(self):
        """
        Testing a simple put
        """

        user = UserFactory()
        amount = 40
        amountChange = 20
        litter = LitterFactory(user=user, amount=amount)

        data = {'typeOfLitter': litter.typeOfLitter,
                'amount': litter.amount + amountChange,
                'timeCollected': litter.timeCollected}

        url = '/litter/' + str(litter.id) + '/'
        request = self.factory.put(url, data, format='json') 
        force_authenticate(request, user=user)
        view = LitterView.as_view()
        response = view(request).render()
        responseData = json.loads(response.content)

无论我做什么,我都无法获得要传递的int:litterId,put函数的默认值始终为0。任何帮助都将不胜感激


Tags: pathfromimportviewrestidurlput
1条回答
网友
1楼 · 发布于 2024-10-01 11:40:38

你的问题是:

response = view(request).render()

您正在手动将请求传递给视图,也没有传递kwarg litterId,而是使用APIClient并向url发出put请求。首先导入所需的模块:

from django.urls import reverse
from rest_framework.test import APIClient

然后:

user = UserFactory()
amount = 40
amountChange = 20
litter = LitterFactory(user=user, amount=amount)
data = {
            'typeOfLitter': litter.typeOfLitter,
            'amount': litter.amount + amountChange,
            'timeCollected': litter.timeCollected
       }

url = reverse('litter-with-id', kwargs={'litterId': litter.id})
client = APIClient()
client.force_authenticate(user=user)
response = client.put(url, data, format='json')

相关问题 更多 >