前戲
在之前我們對前端妹子傳來的數據進行校驗,使用的是序列化類來進行校驗的,但這里面往往滿足不了我們的需求,更多的時候我們希望自己定義校驗規則。這里介紹三種自定義校驗的方式。分別是單一字段校驗,多個字段校驗,還有就是自定義校驗
單一字段校驗
在序列化器BookSerializer自定義一個方法
class BookSerializer(serializers.Serializer): id = serializers.IntegerField(required=False) # 只序列化,不走校驗 title = serializers.CharField(max_length=32, validators=[my_validate]) pub_time = serializers.DateField() category = serializers.CharField(source="get_category_display", read_only=True) # 只序列化用 # 因為前端傳的是數字,所以需要重寫 post_category = serializers.IntegerField(write_only=True) # 只反序列化用 publisher = PublisherSerializer(read_only=True) # 一對多的表 只序列化用 authors = AuthorSerializer(many=True, read_only=True) # 多對多的表需要指定many=True 只序列化用 publisher_id = serializers.IntegerField(write_only=True) # 只反序列化用 author_list = serializers.ListField(write_only=True) # 只反序列化用 def create(self, validated_data): 。。。
def validate_title(self, value): # 對單一字段校驗 if "BDYJY" not in value.upper(): return value raise serializers.ValidationError('標題里含有非法字符') # 拋出錯誤
validate_字段名,這里validate_title,表示只對title字段進行校驗,其他的字段不校驗
這樣當我們傳的值有bdyjy時會提示非法,如下
多個字段校驗
上面的校驗是校驗某一個字段的,有時候我們想校驗多個字段,這時候就要用到validate這個方法了
class BookSerializer(serializers.Serializer): id = serializers.IntegerField(required=False) # 只序列化,不走校驗 title = serializers.CharField(max_length=32) pub_time = serializers.DateField() category = serializers.CharField(source="get_category_display", read_only=True) # 只序列化用 # 因為前端傳的是數字,所以需要重寫 post_category = serializers.IntegerField(write_only=True) # 只反序列化用 publisher = PublisherSerializer(read_only=True) # 一對多的表 只序列化用 authors = AuthorSerializer(many=True, read_only=True) # 多對多的表需要指定many=True 只序列化用 publisher_id = serializers.IntegerField(write_only=True) # 只反序列化用 author_list = serializers.ListField(write_only=True) # 只反序列化用 def create(self, validated_data): ... def validate(self, attrs): # 對多個字段校驗 # attrs是一個字典,里面是傳過來的所有字段 if 'python' in attrs['title'].lower() and attrs['post_category']==1: return attrs else: raise serializers.ValidationError('傳的參數有誤,請重新上傳')
結果:
自定義校驗
上面的兩種校驗要么是單一字段校驗,要么是所有字段校驗,但更多的時候,我們是想讓某些字段校驗這個,某些字段校驗那個,這時候,就要用到自定義校驗了
前面的兩種校驗都是寫在序列化器類里面的,自定義校驗要寫在序列化類外面,哪個字段想用就寫上validators參數,里面是一個列表,放自定義的方法名
def my_validate(value): # 自定義校驗 if "sb" in value.lower(): raise serializers.ValidationError('有臟話') return value
在序列化器里
class BookSerializer(serializers.Serializer): id = serializers.IntegerField(required=False) # 只序列化,不走校驗 title = serializers.CharField(max_length=32, validators=[my_validate]) # validators里傳的是一個列表,里面的是自定義的方法名 pub_time = serializers.DateField() category = serializers.CharField(source="get_category_display", read_only=True) # 只序列化用
這樣哪個字段需要使用自定義的校驗規則了就給哪個字段加上validators參數,里面放上要校驗的方法名就可以了