2017-02-07 105 views
0

我想從使用Django窗體轉換爲只使用REST框架序列化程序的窗體。我的模型是:Django的REST框架序列化一對一模型

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()方法,我用它來驗證數據。我不確定序列化程序是否會執行(無法在文件中找到它)。另外,當我在View類中調用序列化程序的save()時,它要求我爲該序列化程序實現create()方法。

回答

1

有用於創建和序列化

更新情況

drf official docs下面

如果我們希望能夠返回基於我們需要實現一個或兩個驗證數據完整的對象實例的方法.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也有從那裏API文檔Field-level validation下面

您可以通過添加.validate_方法,你的串行子類指定自定義字段級驗證。這些與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 
+0

謝謝!後續問題:有沒有辦法設置多個字段錯誤而不是引發異常?我正在尋找一個類似於django forms'add_error()'方法的函數。 – George

+0

不客氣。我認爲可能的後續答案在這裏[stackoverflow](http://stackoverflow.com/a/31278625/3898339) –

相關問題