简体   繁体   中英

Django Token objects update error : django.db.utils.IntegrityError: UNIQUE constraint failed: authtoken_token.user_id

I was using django user class and rest_framework Token class to store the user info and the token. For the same I was using serializers.ModelSerializer class. But when I am making update request(check update method) to update the user info as well as the token that I have, its giving me error.

Here is serializers.py

from rest_framework import serializers
from django.contrib.auth.models import User
from rest_framework.authtoken.views import Token

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'password']

        extra_kwargs = {
            'password' : {
                'write_only':True,
                'required': True
            }
        }
    
    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)
        Token.objects.create(user=user) # create token for the user
        return user

    def update(self, instance, validated_data):
        instance.username = validated_data['username']
        instance.set_password(validated_data['password'])
        instance.save()
        Token.objects.update(user=instance)

        return instance

views.py

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    permission_classes = [IsAuthenticated, IsOwnerOfObject]
    authentication_classes = (TokenAuthentication,)

urls.py

from django.urls import path, include
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register('users', UserViewSet, basename = 'users')

urlpatterns = [
    path('api/', include(router.urls)),
]

Error :

django.db.utils.IntegrityError: UNIQUE constraint failed: authtoken_token.user_id

This is how I am making the request with the authorisation token in the header field:

在此处输入图片说明

What do you want to achieve?

Token.objects.update(user=instance)

It doesn't make any sense. It is update without WHERE clausule. I think that you "want" to do something like this.

Token.objects.filter(user=instance).update(user=instance)

That query does nothing really. I think that you really want is token invalidation. You must delete the current one and generate new.

This line is invalid:

Token.objects.update(user=instance)

Here, you are trying to update a Token object without specifying which one. You should do .filter() or .get() before updating.

But that statement is reduntant. Think about it, you're updating the token from 'instance' to 'instance'. So, everything will be the same. Try deleting it as it doesn't have any effect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM