我有以下两个模型:
class Student(BaseModel):
external_id = models.CharField(max_length=30)
name= models.CharField(max_length=30)
last_name= models.CharField(max_length=30)
class Book(BaseModel):
student = models.OneToOneField(
"student.Student",
related_name="books",
on_delete=models.CASCADE,
)
book_name = models.CharField(max_length=30)
book_type = models.CharField(max_length=30)
我想创建这样的序列化器,它将只在提供external_id的Student中创建Book。
class BooksSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = [
"student",
"book_name",
"book_type",
]
def create(self, validated_data):
student_external_id = validated_data.pop('student')
st = Student.objects.get(
external_id=student_external_id
)
book = Book.objects.create(
student=st,
book_name=validated_data["book_name"],
book_type=validated_data["book_type"],
)
return book
我已经写了这段代码,但显然它不起作用。我使用嵌套序列化器做类似的事情,但我不想创建学生这次,只检查是否存在,并使用它作为关系,否则抛出错误,这样的学生不存在。也许这首先是一种糟糕的方法?也许我不应该尝试为books创建单独的端点,并尝试为Student使用patch方法并在其中创建对象Book给Student?
您可以使用PrimaryKeyRelatedField。它检查发送的值是否存在,如果不存在则引发ValidationError。试试这个:
class BooksSerializer(serializers.ModelSerializer):
student = serializers.PrimaryKeyRelatedField(queryset=Student.objects.all())
class Meta:
model = Book
fields = [
"student",
"book_name",
"book_type",
]
def create(self, validated_data):
book = Book.objects.create(
student=student,
book_name=validated_data["book_name"],
book_type=validated_data["book_type"],
)
return book
如果你想使用不同于主键的字段,那么你可以使用SlugRelatedField。您应该使用slug_field
键添加查找字段。
class BooksSerializer(serializers.ModelSerializer):
student = serializers.SlugRelatedField(queryset=Student.objects.all(), slug_field='external_id')
class Meta:
model = Book
fields = [
"student",
"book_name",
"book_type",
]
def create(self, validated_data):
book = Book.objects.create(
student=validated_data["student"],
book_name=validated_data["book_name"],
book_type=validated_data["book_type"],
)
return book