0
votes

I am trying to create a simple API to get a user register.

I am using the default User table for authentication purpose, created another table called "phone" with one to one relation with User.

enter image description here

I am trying to add "phone" field just above the password. (I hope the image attached is visible).

**

Serializer.py

class UserRegisterSerializer(serializers.ModelSerializer): class Meta: model = UserDetailsModel fields = ('phone', 'user')

class RegisterSerializer(serializers.ModelSerializer): password = serializers.CharField(max_length=68, min_length=6, write_only=True)

class Meta:
    model = User
    fields = ('username','first_name', 'last_name','email','password')
    read_only_fields = ('id',)

**

models.py<< ** class UserDetailsModel(models.Model):

phone = models.IntegerField()
balance = models.DecimalField(max_digits=10, decimal_places=2, default=0)
user = models.OneToOneField(get_user_model(),primary_key='email' , on_delete=models.CASCADE)

def __str__(self):
    return str(self.user)

**

views.py

** class RegisterView(generics.GenericAPIView): serializer_class = RegisterSerializer

def post(self, request):
    user = request.data
    serializer = self.serializer_class(data=user)
    serializer.is_valid(raise_exception=True)
    serializer.save()

    user_data = serializer.data

    return Response(user_data,status=status.HTTP_201_CREATED)

class DetailsRegisterView(generics.GenericAPIView): serializer_class = UserRegisterSerializer

def post(self, request):
    user = request.data
    serializer = self.serializer_class(data=user)
    serializer.is_valid(raise_exception=True)
    serializer.save()

    user_data = serializer.data

    return Response(user_data,status=status.HTTP_201_CREATED)

**

urls

** urlpatterns = [

path('',RegisterView.as_view()),
path('details', DetailsRegisterView.as_view())

] **

2

2 Answers

0
votes

You probably can use source in a serializer with a FK

class RegisterSerializer(...)
    ...
    phone = serializers.CharField(..., source='userdetails.phone')

see also : the doc

I have some doubt in create case, in a update case this code work fine.

see also : How to serialize a relation OneToOne in Django with Rest Framework?

and an other way to resolve your issue : nested serializer

0
votes

Updated code:

serializers>

from django.contrib.auth.models import User from django.http import JsonResponse

from rest_framework import serializers

from .models import UserDetailsModel

class RegisterSerializer(serializers.ModelSerializer):

class Meta:
    model = User
    fields = ('username','first_name', 'last_name','email','password')
    read_only_fields = ('id',)

class UserRegisterSerializer(serializers.ModelSerializer): user = RegisterSerializer(required=True)

class Meta:
    model = UserDetailsModel
    fields = ('phone','user')

def create(self, validated_data):

    user_data = validated_data.pop('user')

    user = RegisterSerializer.create(RegisterSerializer(), validated_data=user_data)

    data, created = UserDetailsModel.objects.update_or_create(user=user,
                        phone=validated_data.pop('phone'))

    return data

class DetailView(serializers.ModelSerializer): user = RegisterSerializer(read_only=True) class Meta: model = UserDetailsModel fields = ('user','phone')

Remaining code stays the same.