【问题标题】:django.db.utils.IntegrityError: UNIQUE constraint failed: authtoken_token.user_iddjango.db.utils.IntegrityError:唯一约束失败:authtoken_token.user_id
【发布时间】:2019-12-31 12:39:44
【问题描述】:

我是 Django REST 框架的新手,我正在尝试使用 Token 为我的 API 进行单元测试,但它一直抛出 IntegrityError。我研究了许多博客以找到解决方案,但找不到。请帮我解决这个问题。提前致谢。

这是我尝试过的代码

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)

【问题讨论】:

  • 您的Token.objects.create(..) 似乎多次插入相同的user
  • 这个错误到底发生在哪一行?如果您不知道,请显示整个错误跟踪。
  • 在创建令牌Token.objects.create(user=self.superuser)时,我尝试删除self.token.save(),我也尝试将令牌创建代码放入setUpClass()类方法中,但它仍然抛出IntegrityError跨度>

标签: django unit-testing django-rest-framework http-token-authentication


【解决方案1】:

终于,我明白了。我没有注意到我在创建每个用户创建令牌的信号中创建了令牌。谢谢@Willem Van Onsem

【讨论】:

    【解决方案2】:

    唯一约束失败:authtoken_token.user_id 出现此错误是因为数据库中已存在此用户的令牌。因此,当它尝试创建具有相同 user_id 的新令牌时会出错

    如果您查看用户的管理员令牌已经存在

    这是从https://excellencetechnologies.in/blog/django-rest-api-authentication-part5/引用的:

    做一个try-except函数:

    
    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)
    

    【讨论】:

    • 感谢您的回答 Junaid Girkar,我想代码部分的少量更新将有助于使其更具可读性;)
    • @Nozim 进行了一些编辑以提高代码的可读性。随意提及我可以改进的任何其他方法。我是 Stackoverflow 的新手,总是愿意纠正我的错误。
    • 欢迎来到社区!感谢您的修改。现在看起来好多了。
    猜你喜欢
    • 1970-01-01
    • 2015-06-05
    • 2016-04-11
    • 1970-01-01
    • 2022-01-21
    • 2017-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多