Hello guys i'm back again
i have a little trouble about my problem.
I want to create Account
in my Django Project. I extend user model using OneToOneField
.
here is my mode.py
class Account(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone_number = models.CharField(max_length=15, unique=True, null=False, blank=False)
birth_date = models.DateField()
address = models.TextField()
district = models.ForeignKey(District, on_delete=models.CASCADE, related_name='district')
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['created_at', ]
def __str__(self):
return self.user.username
and here is my serializers.py
class UserSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(source='account.id', read_only=True)
phone_number = serializers.CharField(source='account.phone_number')
birth_date = serializers.DateField(source='account.birth_date')
address = serializers.CharField(source='account.address')
class Meta:
model = User
fields = (
'id', 'first_name',
'last_name', 'username',
'email', 'password',
'phone_number', 'birth_date',
'address'
)
def update_or_create_account(self, user, account_data):
Account.objects.update_or_create(user=user, defaults=account_data)
def create(self, validated_data):
account_data = validated_data.pop('account', None)
user = super(UserSerializer, self).create(validated_data)
self.update_or_create_account(user, account_data)
return user
def update(self, instance, validated_data):
account_data = validated_data.pop('account', None)
self.update_or_create_account(instance, account_data)
user = super(UserSerializer, self).update(instance, validated_data)
return user
class AccountSerializer(serializers.ModelSerializer):
user = UserSerializer(required=True)
created_at = serializers.DateTimeField(read_only=True)
class Meta:
model = Account
fields = (
'user',
'district', 'created_at'
)
and here for views.py
class AccountList(APIView):
def get(self, format=None):
account = Account.objects.all()
serializer = AccountSerializer(account, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = AccountSerializer(data=request.data)
if User.objects.filter(email=request.data['user']['email']).exists():
return Response(data={'email': 'Email already taken, use another email'}, status=status.HTTP_400_BAD_REQUEST)
if serializer.is_valid():
serializer.create(validated_data=request.data)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.error_messages,
status=status.HTTP_400_BAD_REQUEST)
and when i try to POST
some Account.
i got this error
The ".create()" method does not support writable nested fields by default.
Write an explicit ".create()" method for serializer "account.serializers.AccountSerializer", or set "read_only=True" on nested serializer fields.
can someone help me ? i don't really understand about this error
Thank you :)
i have answer for my question.
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username', 'email', 'password', 'first_name', 'last_name')
class AccountSerializer(serializers.ModelSerializer):
user = UserSerializer()
created_at = serializers.DateField(read_only=True)
class Meta:
model = Account
fields = ('user', 'phone_number', 'birth_date', 'address', 'district', 'created_at')
def create(self, validated_data):
user_data = validated_data.pop('user')
user = User.objects.create(
username=user_data['username'],
email=user_data['email'],
first_name=user_data['first_name'],
last_name=user_data['last_name']
)
user.set_password(user_data['password'])
user.save()
account = Account.objects.create(
user=user,
phone_number=validated_data['phone_number'],
birth_date=validated_data['birth_date'],
address=validated_data['address'],
district=validated_data['district']
)
return account