JimVanB
JimVanB

Reputation: 1225

Django REST Framework Serializer output

I'am new to Django and DRF, but I'am trying to use DRF's Serializer to override djosers default user registration behavior.
(djoser = a DRF lib for user registration/login/password reset etc.)

I've djosers view, that uses a serializer to create user objects
def perform_create(self, serializer): user = serializer.save()

My idea was to override this serializer to achieve the following:

  1. create the user
  2. create an account object in parallel
  3. login the user
  4. return the account object alongside with the auth token in one response

The last point gives me trouble because I don't know how to achieve such custom behavior in the serializer. I made the input fields readonly, so they are not included in my response. In the save method a create a user + account object, logging in the user and then I return the user (which is needed by the view)
How do I serialize just the created account object with the created token string into one response?

This is my serializer (simplified and stripped from some stuff, but that's basically it)

class UserRegistrationSerializer(serializers.Serializer):
email = serializers.EmailField(write_only=True)
# some other fields
password = serializers.CharField(style={'input_type': 'password'},
                                 write_only=True,
                                 validators=settings.get('PASSWORD_VALIDATORS')
                                 )
# this should be the output
account = Account(read_only=True)

def save(self):
    user = User(email=self.validated_data['email'])
    user.set_password(self.validated_data['password'])
    user.save()

    account = Account(user=user)
    token = #logging in my user 

    return user

Upvotes: 1

Views: 1333

Answers (1)

theguru42
theguru42

Reputation: 3378

use this:

class UserRegistrationSerializer(serializers.ModelSerializer):
    email = serializers.EmailField(write_only=True)
    # some other fields
    password = serializers.CharField(
                               style={'input_type': 'password'},
                               write_only=True,
                               validators=settings.get('PASSWORD_VALIDATORS')
                               )
    # make sure you have related_name='account' in your one to one field
    account = AccountSerializer(read_only=True)
    # the token field
    auth_token = TokenSerializer(read_only=True)

    class Meta:
        model = User
        # define fields based on your needs
        fields = ...

    def create(self, validated_data):
        user = User(email=self.validated_data['email'])
        user.set_password(self.validated_data['password'])
        user.save()
        # create account
        account = Account(user=user)
        # create token for user
        token = Token.objects.update_or_create(user=user) 
        return user

you'll also need to create an update method based on your custom needs.

Upvotes: 2

Related Questions