0

I'm new in Django rest framework and I'm trying do a unit test using Token for my API, but it kept throwing IntegrityError. I've researched many blogs to find the solution but couldn't find. Please help me solve this. Thanks in advance.

Here is the code that I've tried

from django.contrib.auth.models import User
from rest_framework.test import APITestCase, APIRequestFactory, force_authenticate
from rest_framework.authtoken.models import Token

from myapp.api.views import UserViewSet


class UserTestCase(APITestCase):
    def setUp(self):
        self.superuser = User.objects.create_user(username='superuser', email='uid.sawyer@gmail.com',
                                                  password='superuser',
                                                  is_staff=True)
        self.factory = APIRequestFactory()

        self.token = Token.objects.create(user=self.superuser)
        self.token.save()

    def test_list(self):
        request = self.factory.get('/api/users/')
        force_authenticate(request, user=self.superuser, token=self.token)
        response = UserViewSet.as_view({'get': 'list'})(request)
        self.assertEqual(response.status_code, 200)
Roshan Maharjan
  • 162
  • 1
  • 11
  • 3
    You seem to insert the same `user` multiple times with your `Token.objects.create(..)` – Willem Van Onsem Aug 27 '19 at 10:38
  • on which line exactly is this error happening? if you don't know, please show the entire error trace. – dirkgroten Aug 27 '19 at 10:58
  • Its when creating token ```Token.objects.create(user=self.superuser)```, I gave a try by removing ```self.token.save()``` and I've also tried to put the token creation code in ```setUpClass()``` classmethod but it's still throwing the IntegrityError – Roshan Maharjan Aug 27 '19 at 11:04

2 Answers2

3

unique constraint failed: authtoken_token.user_id This error is coming because token already exists for this user in database. So when it tries to create new token with same user_id it gives an error

If you look at the admin token already exists for users

This is referenced from https://excellencetechnologies.in/blog/django-rest-api-authentication-part5/:

Do a try-except function:


class UserAuth(APIView):

   # Manager User Login and other things
    

    def post(self, request):
        
        # login
       
        user = authenticate(
            username=request.data.get("username"),
            password=request.data.get("password")
            )
        if user is not None:
            # A backend authenticated the credentials

            try:
                token = Token.objects.get(user_id=user.id)

            except Token.DoesNotExist:
                token = Token.objects.create(user=user)

            return Response(token.key)

        else:
            # No backend authenticated the credentials
            return Response([], status=status.HTTP_401_UNAUTHORIZED)
  • thanks for your answer Junaid Girkar, I suppose little update of code section would help to make it more readable ;) – Nozim Sep 25 '20 at 12:01
  • @Nozim Have made some edits to improve the readability of the code. Feel free to mention any other ways I can improve. Am new to Stackoverflow and am always willing to correct my mistakes. – Junaid Girkar Sep 26 '20 at 13:24
  • Welcome to the community! Thanks for the modifications. It's looks much better now. – Nozim Nov 13 '20 at 07:05
1

Finally, I got it. I didn't notice that I had created Token in signals wherein each User creation Token was created. Thanks @Willem Van Onsem

Roshan Maharjan
  • 162
  • 1
  • 11