Reputation: 3
I understand that the default user model does not have a field named 'phone'. However, I am trying to retrieve all the registered users from the default user model, along with additional fields such as 'phone', 'phone_verified', 'email_verified', 'phone_code', and 'email_code' from a custom UserProfile model which inherits from the default user model using a OneToOneField. To achieve this, I have created a UserSerializer which serializes the default User model, and a nested UserProfileSerializer that utilizes the UserSerializer class and the UserProfile model. My goal is to have the nested UserProfileSerializer serialize data from both the user model and the custom UserProfile model. Unfortunately, I am encountering the following error: AttributeError at /register/ - Got AttributeError when attempting to get a value for field 'user' on serializer 'UserProfileSerializer'. The serializer field might be named incorrectly and not match any attribute or key on the 'User' instance. The original exception text was: 'User' object has no attribute 'user'.
models.py:
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone = models.CharField(max_length=20)
phone_verified = models.BooleanField(default=False)
email_verified = models.BooleanField(default=False)
phone_code = models.CharField(max_length=10)
email_code = models.CharField(max_length=10)
serializer.py:
from django.core import validators
from rest_framework import serializers
from django.contrib.auth.models import User
from .models import UserProfile
from datetime import datetime
class UserSerializer(serializers.ModelSerializer):
first_name = serializers.CharField(required=True)
last_name = serializers.CharField(required=True)
registration_data = serializers.DateTimeField(
read_only=True, default=serializers.CreateOnlyDefault(datetime.now())
)
password = serializers.CharField(
required=True,
write_only=True,
max_length=128, # Maximum length for Django password
error_messages={
'required': 'Please enter a password.',
'max_length': 'Password should be no more than 128 characters.'
},
validators=[
validators.MinLengthValidator(8, message='Password must be at least 8 characters.'),
validators.RegexValidator(
regex=r'[A-Z]',
message='Password must contain at least one uppercase letter.',
code='invalid_password'
),
validators.RegexValidator(
regex=r'[a-z]',
message='Password must contain at least one lowercase letter.',
code='invalid_password'
),
validators.RegexValidator(
regex=r'[0-9]',
message='Password must contain at least one number.',
code='invalid_password'
),
validators.RegexValidator(
regex=r'[!@#$%^&*()]',
message='Password must contain at least one special character.',
code='invalid_password'
)
]
)
class Meta:
model = User
exclude = ['id']
class UserProfileSerializer(serializers.ModelSerializer):
user = UserSerializer(required=True)
class Meta:
model = UserProfile
fields = ('user', 'phone', 'phone_verified', 'email_verified', 'phone_code', 'email_code')
# exclude = ['id']
views.py:
from django.contrib.auth.models import User
from rest_framework import generics
from .serializer import UserSerializer, UserProfileSerializer
class RegisterUserView(generics.CreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('register/', views.RegisterUserView.as_view(), name='register')
]
Upvotes: 0
Views: 344
Reputation: 224
I've noticed that you are experiencing several different errors from your description. Sharing the entire error message can help people to give a more direct answer!
Here are a few suggestions I'd like to make based on common django practices. Might not be the most quick fix but can help you down the way, I hope.
'AttributeError: 'User' object has no attribute 'phone'' in Django
Since django's User
model does not have phone
field (in currently available Django versions), you added UserProfile
model. I think that's great. Along with UserProfile
model, if you also define your own custom user model (in the simplest form), it will give you much more flexibility. (ref)
Can be as simple as this:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
(and if you define a custom user model, one might think 'why not add phone field here?'. yeah, but that depends on your project's requirements. and i think UserProfile
as a separate model is still a good choice.bb)
AttributeError at /register/ - Got AttributeError when attempting to get a value for field 'user' on serializer 'UserProfileSerializer'. The serializer field might be named incorrectly and not match any attribute or key on the 'User' instance.
'User' object has no attribute 'user'.
These messages seems incomplete to find a definite answer. But something that can help this sort of issue is letting django know "which is which" using AUTH_USER_MODEL
in settings and django's get_user_model.
My goal is to have the nested UserProfileSerializer serialize data from both the user model and the custom UserProfile model.
I assumed that the intention of nested serializer in your code was implementing user registration with required phone number. If that's the case, I think adding a simple custom user model along with your UserProfile
could make this easier. and help you debug the errors you shared here.
Hope this helps!
Upvotes: 0