Как заставить этот REST-запрос Django отображать все поля, включая поля из связанной таблицы один-к-одному

Это мой Django models.py с 2 таблицами, имеющими отношения один-к-одному. Модель UserComputedInfo имеет отношения один-к-одному с моделью CustomUser.

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

Я пытаюсь создать REST API для отображения всех полей в 2 таблицах. Я использую фреймворк Django REST.

Это моя serializers.py

from rest_framework import serializers
from users.models import CustomUser


class CustomUserSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ("email", "post_code")
        model = CustomUser

Это моя 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

API отображает все поля в таблице CustomUser. Однако, я хочу отобразить все поля в связанной один к одному таблице UserComputedInfo, также.

Я использую Django v4, python v3.9, Django REST framework на Windows 10.

вы можете использовать UserComputedInfoSerializer в CustomUserSerializer вот так

# 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

если вы хотите, чтобы это было только read_only так UserComputedInfoSerializer(read_only=True) остальным следует обрабатывать операции вручную и для UserComputedInfoSerializer тоже.

Я отвечу на свой собственный вопрос. Он был протестирован и успешно работает.

# 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 

В https://www.django-rest-framework.org/api-guide/serializers/#modelserializer указано, что the ModelSerializer class provides a shortcut that lets you automatically create a Serializer class with fields that correspond to the Model fields.

Поле usercomputedinfo соответствует таблице "один-к-одному" UserComputedInfo. Обратите особое внимание, что именование поля соответствует соглашению, используемому ModelSerializer. В данном случае оно должно быть полностью строчным. Если вы используете в качестве поля UserComputedInfo, оно не будет работать. Я не могу найти документацию по соглашению об именовании полей, используемому ModelSerializer. depth = 1 необходим для генерации вложенных представлений.

Иногда вместо того, чтобы отображать все поля, мы хотим указать конкретные поля. Вот код для этого.

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
        
Вернуться на верх