Search code examples
djangodjango-rest-frameworkdjango-allauthdjango-rest-auth

Django-Rest-Auth: Require another field at registration


I am managing some userdata using Django. I would like to offer the humans behind that data the possibility to take a look at it by registering and connecting their accounts to the existing data (at once).

I therefore handle them a authentification-token, printed on a sheet of paper, in order to connect their already existing data to their accounts they have to send that token along with their desired username, email, password etc.

My Userdata Model looks like this:

class Userdata(models.Model):
    number = models.IntegerField(primary_key=True)
    first_name = models.CharField(max_length=128)
    last_name = models.CharField(max_length=128)
    useraccount = models.OneToOneField(get_user_model())
    auth_token = models.CharField(max_length=12, default="DUMMY", unique=True)

Therefore I would like to change the registration process, using djang-rest-auth and allauth to check if there exists a row in the userdata table where the auth_token equals the provided one at the registration.

If, then I would like to set the useraccount field in this row to the newly created account, if not, then I would like to raise an error and stop the registration of the account.


I am totally lost at the moment and have no idea where to start. I would really appreaciate any hint into the right direction.

Thank you!


Solution

  • Thanks to @somil I came finally up with the following working but yet dirty solution

    from rest_auth.registration.serializers import RegisterSerializer
    from apps.FOOBAR.models import Userdata
    
    # ...
    
    class TokenRegisterSerializer(RegisterSerializer):
        pass
    
        # adding the token field to the default serializer
        token = serializers.CharField(write_only=True)
    
        # adding a token validator: check if there is a userdata with this token
        def validate_token(self, token):
            try:
                Userdata.objects.get(auth_token=token)
                return token
            except Patient.DoesNotExist:
                raise serializers.ValidationError(
                    "Token seems to be invalid, try again")
    
        # this method is called at save
        def custom_signup(self, request, user):
            # connect the data with the user
            data = Userdata.objects.get(
                auth_token=self.validated_data.get('token', ''))
            data.useraccount = user
            data.save()
    

    And, in the settings.py

    REST_AUTH_REGISTER_SERIALIZERS = {
        'REGISTER_SERIALIZER': 'apps.api.serializers.TokenRegisterSerializer',
    }