This is my Django models.py
with 2 tables having a one-to-one table relationship. UserComputedInfo model has a one-to-one relationship with CustomUser model.
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.contrib.auth import get_user_model
class CustomUser(AbstractUser):
email = models.EmailField(unique=True)
post_code = models.DecimalField(max_digits=9, decimal_places=6)
def __str__(self):
return self.username
class UserComputedInfo(models.Model):
user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE)
copy_input = models.DecimalField(max_digits=9, decimal_places=6)
def __str__(self):
return self.copy_input
I am trying to create a REST API to display all the fields in the 2 tables. I am using Django REST framework.
This is my serializers.py
from rest_framework import serializers
from users.models import CustomUser
class CustomUserSerializer(serializers.ModelSerializer):
class Meta:
fields = ("email", "post_code")
model = CustomUser
This is my views.py
from rest_framework import generics
from django.contrib.auth import get_user_model
from .serializers import CustomUserSerializer
class PostCodeAPIView(generics.ListAPIView):
queryset = get_user_model().objects.all()
serializer_class = CustomUserSerializer
The API will display all the fields in CustomUser
table. However, I want to display all the fields in the related one-to-one UserComputedInfo
table as well.
I am using Django v4, python v3.9, Django REST framework on Windows 10.
CodePudding user response:
you can use UserComputedInfoSerializer
in CustomUserSerializer
like this
# serializers.py
from rest_framework import serializers
from users.models import CustomUser, UserComputedInfo
class UserComputedInfoSerializer(serializers.ModelSerializer):
class Meta:
model = UserComputedInfo
fields = "__all__"
class CustomUserSerializer(serializers.ModelSerializer):
UserComputedInfo = UserComputedInfoSerializer(source="usercomputedinfo")
class Meta:
fields = ("email", "post_code", "UserComputedInfo")
model = CustomUser
if you want it only read_only
so UserComputedInfoSerializer(read_only=True)
else should handle the operations manually for UserComputedInfoSerializer
too.
CodePudding user response:
I will answer my own question. It has been tested to work successfully.
# serializers.py
from rest_framework import serializers
from users.models import CustomUser
class CustomUserSerializer(serializers.ModelSerializer):
class Meta:
fields = ("email", "post_code", "usercomputedinfo")
model = CustomUser
depth = 1 # display all the fields in related 1-to-1 table
In https://www.django-rest-framework.org/api-guide/serializers/#modelserializer, it is stated that the ModelSerializer class provides a shortcut that lets you automatically create a Serializer class with fields that correspond to the Model fields.
The field usercomputedinfo
corresponds to the one-to-one table UserComputedInfo
. Take special note that the naming of the field follows a convention used by ModelSerializer. In this case, it has to be all lowercase. If you use UserComputedInfo
as the field, it won't work. I cannot find the documentation on the field naming convention used by ModelSerializer. depth = 1
is needed to generate nested representations.
Instead of displaying all the fields, sometimes we want to specify specific fields. This is the code for doing it.
from rest_framework import serializers
from users.models import CustomUser, UserComputedInfo
class UserComputedInfoSerializer(serializers.ModelSerializer):
class Meta:
model = UserComputedInfo
fields = ("copy_input")
class CustomUserSerializer(serializers.ModelSerializer):
usercomputedinfo = UserComputedInfoSerializer()
class Meta:
fields = ("email", "postal_code", "usercomputedinfo")
model = CustomUser