【问题标题】:Overriding the create method of Django Rest Framework Serialization覆盖 Django Rest Framework 序列化的 create 方法
【发布时间】:2021-01-16 15:29:36
【问题描述】:

我正在创建一个Django 后端,我使用Django Rest Framework 来构建REST API

我有嵌套序列化,当我尝试序列化数据时,我必须重写 ModelSerializers 的创建函数。我有点害怕这会导致后端安全性出现问题或漏洞,因为我在创建对象时没有使用默认验证。

那么这样做正常吗?


# THIS IS MY MODELS.PY

from django.db import models
from django.contrib.auth.models import User

class UnivStudent(models.Model):
    """
    A class based model for storing the records of a university student
    Note: A OneToOne relation is established for each student with User model.
    """
    user = models.OneToOneField(User)
    subject_major = models.CharField(name="subject_major", max_length=60)
# THIS IS MY SERIALIZERS.PY 

from rest_framework import serializers, status
from models import *


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email')


class StudentSerializer(serializers.ModelSerializer):
    """
    A student serializer to return the student details
    """
    user = UserSerializer(required=True)

    class Meta:
        model = UnivStudent
        fields = ('user', 'subject_major',)

    def create(self, validated_data):
        """
        Overriding the default create method of the Model serializer.
        :param validated_data: data containing all the details of student
        :return: returns a successfully created student record
        """
        user_data = validated_data.pop('user')
        user = UserSerializer.create(UserSerializer(), validated_data=user_data)
        student, created = UnivStudent.objects.update_or_create(user=user,
                            subject_major=validated_data.pop('subject_major'))
        return student

最后,

# THIS IS MY VIEWS.PY


from serializers import *
from models import *
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status


class StudentRecordView(APIView):
    """
    A class based view for creating and fetching student records
    """
    def get(self, format=None):
        """
        Get all the student records
        :param format: Format of the student records to return to
        :return: Returns a list of student records
        """
        students = UnivStudent.objects.all()
        serializer = StudentSerializer(students, many=True)
        return Response(serializer.data)

    def post(self, request):
        """
        Create a student record
        :param format: Format of the student records to return to
        :param request: Request object for creating student
        :return: Returns a student record
        """
        serializer = StudentSerializer(data=request.data)
        if serializer.is_valid(raise_exception=ValueError):
            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)

【问题讨论】:

    标签: python python-3.x django django-rest-framework


    【解决方案1】:

    这是一个不好的方法,你应该参考PrimaryKeyRelatedFieldSerializerMethodField 来重新构建你的序列化器。我相信您可以解决 Serializer 中的嵌套序列化问题,无需在 View 中自定义。

    【讨论】:

      【解决方案2】:

      进行如下更改:它们与原始框架中的相同。

      class UserSerializer(serializers.ModelSerializer):
          class Meta:
              model = User
              fields = ('username', 'first_name', 'last_name', 'email')
      
      
      class StudentSerializer(serializers.ModelSerializer):
          """
          A student serializer to return the student details
          """
          user = UserSerializer(required=True)
      
          class Meta:
              model = UnivStudent
              fields = ('user', 'subject_major',)
      
          def create(self, validated_data):
              """
              Overriding the default create method of the Model serializer.
              :param validated_data: data containing all the details of student
              :return: returns a successfully created student record
              """
              user_data = validated_data.pop('user')
              original_user_data = self.initial_data.get('user')
              user_serializer = UserSerializer(data=original_user_data)
              user_serializer.is_valid(raise_exception=True)
              user = user_serializer.save()
              # user = UserSerializer.create(UserSerializer(), validated_data=user_data)
              validated_data['user'] = user
              return super(StudentSerializer, self).create(validated_data)
              # student, created = UnivStudent.objects.update_or_create(user=user,
              #                    subject_major=validated_data.pop('subject_major'))
              # return student
      

      和查看

      class StudentRecordView(APIView):
          """
          A class based view for creating and fetching student records
          """
          def get(self, format=None):
              """
              Get all the student records
              :param format: Format of the student records to return to
              :return: Returns a list of student records
              """
              students = UnivStudent.objects.all()
              serializer = StudentSerializer(students, many=True)
              return Response(serializer.data)
      
          def post(self, request):
              """
              Create a student record
              :param format: Format of the student records to return to
              :param request: Request object for creating student
              :return: Returns a student record
              """
              serializer = StudentSerializer(data=request.data)
              serializer.is_valid(raise_exception=True)
              serializer.save() 
              return Response(serializer.data, status=status.HTTP_201_CREATED)
      

      【讨论】:

        猜你喜欢
        • 2015-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多