我正在尝试从使用Django表单转换为仅使用表单的REST Framework序列化程序。我的模特是:
class UserDetails(models.Model):
user = models.OneToOneField(User, related_name='details', on_delete=models.CASCADE)
date_of_birth = models.DateField(default=None, blank=True, null=True)
class Employee(models.Model):
user = models.OneToOneField(User, related_name='employee', on_delete=models.CASCADE)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
class Company(models.Model):
name = models.CharField(verbose_name='Company Name', max_length=50, unique=True)
info = models.CharField(verbose_name='Company Information', max_length=300, blank=True)
我有User,UserDetails和Company的序列化程序。
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = models.User
fields = ('id', 'username', 'email', 'first_name', 'last_name', )
class UserDetailsSerializer(serializers.ModelSerializer):
user = UserSerializer()
class Meta:
model = models.UserDetails
fields = ('user', 'date_of_birth')
read_only_fields = ('is_verified',)
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model = models.Company
fields = ('name', 'info')
当用户注册时,他们还将指定公司信息并成为该公司的员工。如何创建表单以原子方式创建所有三个记录?
这是我的尝试:
class RegistrationSerializer(serializers.Serializer):
details = UserDetailsSerializer(label='')
password = serializers.CharField(
label='Password',
style={'input_type': 'password'}
)
password2 = serializers.CharField(
label='Password Confirmation',
style={'input_type': 'password'}
)
company = CompanySerializer()
我还想要一个密码确认字段,如果表单不匹配,将导致表单无效。 Django表单有一个clean()
方法,我用它来验证数据。我不确定序列化器是否(在doucmentation中找不到它)。另外,当我在我的View类中调用序列化程序的save()
时,它要求我为序列化程序实现create()
方法。
答案 0 :(得分:1)
有一些在序列化程序中创建和更新实例的方法
如果我们希望能够根据验证的数据返回完整的对象实例,我们需要实现.create()和update()方法中的一个或两个。例如:
class CommentSerializer(serializers.Serializer):
email = serializers.EmailField()
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
def create(self, validated_data):
return Comment(**validated_data)
def update(self, instance, validated_data):
instance.email = validated_data.get('email', instance.email)
instance.content = validated_data.get('content', instance.content)
instance.created = validated_data.get('created', instance.created)
return instance
drf也有Field-level validation来自下面的api文档
您可以通过将.validate_方法添加到Serializer子类来指定自定义字段级验证。这些类似于Django表单上的.clean_方法。 这些方法采用单个参数,即需要验证的字段值。 您的validate_方法应该返回验证值或引发serializers.ValidationError。例如:
from rest_framework import serializers
class BlogPostSerializer(serializers.Serializer):
title = serializers.CharField(max_length=100)
content = serializers.CharField()
def validate_title(self, value):
"""
Check that the blog post is about Django.
"""
if 'django' not in value.lower():
raise serializers.ValidationError("Blog post is not about Django")
return value