1

I have 2 models, Account model as shown

class Account(AbstractBaseUser,PermissionsMixin):
    email = models.EmailField(max_length=100, unique = True)
    username = models.CharField(max_length = 30)
    is_admin = models.BooleanField(default = False)
    is_staff = models.BooleanField(default = False)
    is_active = models.BooleanField(default = False)
    date_joined = models.DateTimeField(auto_now_add = True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = [
       'username'
    ]

and the profile table as shown below

class Profile(models.Model):
    user = models.OneToOneField(Account, on_delete = models.CASCADE)
    avatar = models.ImageField(default = "defaultpic.png", blank = True, null = True, upload_to="MEDIA_FILES" )
    tel = PhoneField(blank=False, null = False)

ProfileSerializer

class ProfileSerializer(serializers.ModelSerializer):
class Meta:
    model = Profile
    fields = [
        'avatar',
        'tel',
    ]

UserSerializer

class AccountSerializer(serializers.ModelSerializer):
profile = ProfileSerializer(read_only = True)

class Meta:
    model = get_user_model()
    fields = [
        'email',
        'username',
        'password',
        'profile'
    ]

    extra_kwargs = {
'password': {'write_only': True},
}

def create(self, validated_data):
    user_password = validated_data.pop('password')
    user = get_user_model()(
    email = validated_data['email'],
    username = validated_data['username']
    )
    user.set_password(user_password)
    user.save()

    user.email_user("Hello world")

    return user

Endpoint to register a new user

@api_view(["POST"]) @permission_classes([AllowAny, ])

def register(request): profSerializer = ProfileSerializer( data = request.data ) serializer = AccountSerializer( data = request.data )

if serializer.is_valid():
    serializer.save()
    serializer.send_mail("Hello")
    return JsonResponse( serializer.data )

else:
    print( serializer.errors )
    return JsonResponse(  { "_err": serializer.errors }  )

My problem now comes in when I send a post request to the registering endpoint, the profile fields remain empty, the avatar field is assigned the default value of default.png. I need the endpoint to create both user account and profile entries whenever a user sign up

The post request to the endpoint is the following JSON

{
      email:"some email",
      username:"username",
      password:"password",
      tel:"tel number",
      avatar:"image"
    }

1 Answer 1

1

In your AccountSerializer you have set the profile field to read only:

profile = ProfileSerializer(read_only=True)

This means the field will be neglected and will not be shown in request.data.

Then you need a little change in your create method, something like this:

def create(self, validated_data):
    profile_data = validated_data['profile']

    # user creation steps
    ...

    profile = Profile(
        user=user,
        **profile_data
    )
    profile.save()

    return user

rest_framework cannot create related objects by default, this is why you need to create an account instance first, and then create a Profile by yourself

Then, you do not need to serialize request.data with ProfileSerializer in your view, remove the line and change the request body to:

{
    email:"some email",
    username:"username",
    password:"password",
    profile: {
        tel:"tel number",
        avatar:"image"
    }
}

I suggest you learning about nested serializers and how they work

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.