Reputation: 49
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"
}
Upvotes: 1
Views: 145
Reputation: 1520
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
Upvotes: 1