2021年1月26日星期二

How can I pass in url arguments to an APIRequestFactory put request?

I have been trying for hours but cannot figure out how to pass a url argument through an APIRequestFactory put request. I have tried it through Postman when running my server and the url variable is passed just fine, but when I run it in my tests it stops working.

What I mean is that when I send a Postman PUT request to '/litter/1/' it will successfully take in the 1 as the variable litterId since my url is setup like this

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

and

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

But when I try and send an APIRequestFactory put request to that same url, for some reason the 1 will not go through as the litterId anymore.

Some relevant pieces of code...

My top level 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')),  ]  

This is my app specific urls.py

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

Here is my views.py

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)  

And here is the relevant test.

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)  

No matter what I do, I cannot get the int:litterId to get passed in, the put function always has the default value of 0. Any help would be greatly appreciated.

https://stackoverflow.com/questions/65912764/how-can-i-pass-in-url-arguments-to-an-apirequestfactory-put-request January 27, 2021 at 12:08PM

没有评论:

发表评论