Search code examples
pythondjangodjango-rest-frameworkdjango-rest-auth

Rewriting DRF token auth


I wanted to allow a user to have multiple tokens so decided to rewrite the Token model. As result created

class TokenAuthentication(rest_framework.authentication.TokenAuthentication):
    model = Token

In my settings added to REST_FRAMEWORK

'DEFAULT_AUTHENTICATION_CLASSES': (
    'users.authentication.TokenAuthentication',
)

Also modified

class ObtainAuthToken(APIView):
    authentication_classes = ()
    throttle_classes = ()
    permission_classes = ()
    parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,)
    renderer_classes = (renderers.JSONRenderer,)
    serializer_class = AuthTokenSerializer


    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        name = serializer.validated_data['name']
        token, created = Token.objects.get_or_create(user=user, name=name)
        return Response({'token': token.key})


obtain_auth_token = ObtainAuthToken.as_view()

and AuthTokenSerializer to return the name

Finaly in the urls got

url(r'^token-auth/', obtain_auth_token),

I think all is correct but keep getting the errors

 File "/home/me/code/python/OCManager/core/users/authentication.py", line 4, in <module>
    from rest_framework.views import APIView
ImportError: cannot import name 'APIView'

and

ImportError: Could not import 'users.authentication.TokenAuthentication' for API setting 'DEFAULT_AUTHENTICATION_CLASSES'. ImportError: cannot import name 'APIView'.

Any hint what it could be?

The Token class modification is this:

class Token(rest_framework.authtoken.models.Token):
    # key is no longer primary key, but still indexed and unique
    key = models.CharField(_("Key"), max_length=40, db_index=True, unique=True)
    # relation to user is a ForeignKey, so each user can have more than one token
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, related_name='auth_tokens',
        on_delete=models.CASCADE, verbose_name=_("User")
    )
    name = models.CharField(_("Name"), max_length=64)

    class Meta:
        unique_together = (('user', 'name'),)

    def __str__(self):
        return self.user.username + " - " + self.name

Solution

  • I managed to find what was wrong. Having the TokenAuth extension in the same file was causing some import error, seems trying to import itself in other file. The solution was moving

    class TokenAuthentication(rest_framework.authentication.TokenAuthentication):
        model = Token
    

    to another file