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.
Aucun commentaire:
Enregistrer un commentaire