Django 重用模型序列化器自定义验证器

问题描述 投票:0回答:1

我有下面的serializer.py 文件。我有 validate_semester() 存在于 subjectSerializer() 中,我想在我的 StudentSerializer() 类中重用相同的方法。任何帮助表示赞赏。 validate_semester() 正在验证学期表中是否存在学期 ID,然后再将其分配给学生或主题对象。

from rest_framework import serializers
from .models import *
from .helpers import SEMESTER_NOT_STORED


class SemesterSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False)
    name = serializers.CharField(max_length=100, required=False)


class SubjectSerializer(serializers.ModelSerializer):
    semester = SemesterSerializer()

    class Meta:
        model = Subject
        fields = ["id", "name", "code", "semester"]

    def create(self, validated_data):
        semester = validated_data.pop("semester")
        serializer = SemesterSerializer(semester)
        subject = Subject.objects.create(
            semester_id=serializer.data["id"], **validated_data
        )
        return subject

    def validate_semester(self, value):
        id = value.get("id")
        try:
            Semester.objects.get(id=id)
        except Semester.DoesNotExist:
            raise serializers.ValidationError({"id":[SEMESTER_NOT_STORED.format(id)]})
        return value


class SemesterSubjectSerializer(serializers.ModelSerializer):
    subjects = SubjectSerializer(many=True, read_only=True)

    class Meta:
        model = Semester
        fields = ["id", "name", "subjects"]


class StudentSerializer(serializers.ModelSerializer):
    semester = SemesterSerializer()

    class Meta:
        model = Student
        fields = ["id", "name", "email", "semester"]

    def create(self, validated_data):
        semester = validated_data.pop("semester")
        serializer = SemesterSerializer(semester)
        student = Student.objects.create(
            id=None, semester_id=serializer.data["id"], **validated_data
        )
        return student

我也尝试在模型级别添加验证,但似乎没有成功。无论如何,我遇到了 IntegrityError。

from django.core.validators import MinLengthValidator, MaxLengthValidator
from .helpers import SEMESTER_NOT_STORED

def validate_semester(id):
    semesters = list(Semester.objects.all().values_list("id", flat=True))
    if id not in semesters:
        raise ValueError({"id":[SEMESTER_NOT_STORED.format(id)]})

class Semester(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class Student(models.Model):
    name = models.CharField(max_length=30)
    email = models.EmailField()
    semester = models.ForeignKey(Semester, on_delete=models.DO_NOTHING, default=None, validators=[validate_semester])

django django-rest-framework django-serializer
1个回答
0
投票

使用序列化器

PrimaryKeyRelatedField
创建一个通用序列化器。它只允许现有的学期实例。无需手动验证。继承学期和学生序列化器类中的通用序列化器类。无需编写验证和创建方法。有关序列化器字段的更多知识,请参阅 REST 框架的序列化器文档。 单击此处查看文档

from rest_framework import serializers
from .models import *


class CommonSemesterValidateSerializer(serializerz.ModelSerializer):
    semester = serializers.PrimaryKeyRelatedField(queryset=Semester.objects.all(), required=True)

    class Meta:
        fields = ["id", "name", "semester"]

class SubjectSerializer(CommonSemesterValidateSerializer):

    class Meta(CommonSemesterValidateSerializer.Meta):
        model = Subject
        fields = CommonSemesterValidateSerializer.Meta.fields + ["code"]

class StudentSerializer(CommonSemesterValidateSerializer):

    class Meta(CommonSemesterValidateSerializer.Meta):
        model = Student
        fields = CommonSemesterValidateSerializer.Meta.fields + ["email"]
© www.soinside.com 2019 - 2024. All rights reserved.