2016-10-26 52 views
0

我不理解django rest框架驗證過程。 doc say驗證完全在序列化程序類上執行。Django rest框架在自己驗證之前做模型字段驗證

但是, 對於模型中的PositiveIntegerField,當ModelSerializer接收到負值時,將在自定義ModelSerializer validate_myfield方法之前處理模型驗證。

class Blop(models.Model): 
    quantity = models.PositiveSmallIntegerField() 

class BlopSerializer(serializers.ModelSerializer): 
    def validate_quantity(self, value): 
     return max(15, value) 

    class Meta: 
     model = Blop 

如果數量比是否爲零較小,validate_quantity不會被調用......

我也試過:

  • 使用模型「乾淨」的方法,但其餘的框架不用它。
  • 通過MIN_VALUE設置爲none禁用最小值驗證模型,但它使其餘的框架崩潰
  • 強制MinValueValidator模型領域:validators=[MinValueValidator(-math.inf, 'Minimum value is -Infinity')],它的工作,但它太醜陋

哪有在這種情況下,我確實有一個序列化程序確保非負值?

回答

1

我認爲你的問題是你正在調用serializer.is_valid()方法沒有kwargs或。 使用raise_exception=True如果您傳遞了無效數據,則串行器會提升ValidationError

爲了更好的理解,我們來看看Serializer.to_internal_value方法。

def to_internal_value(self, data): 
    """ 
    Dict of native values <- Dict of primitive datatypes. 
    """ 
    if not isinstance(data, dict): 
     message = self.error_messages['invalid'].format(
      datatype=type(data).__name__ 
     ) 
     raise ValidationError({ 
      api_settings.NON_FIELD_ERRORS_KEY: [message] 
     }) 

    ret = OrderedDict() 
    errors = OrderedDict() 
    fields = self._writable_fields 

    for field in fields: 
     validate_method = getattr(self, 'validate_' + field.field_name, None) 
     primitive_value = field.get_value(data) 
     try: 
      validated_value = field.run_validation(primitive_value) 
      if validate_method is not None: 
       validated_value = validate_method(validated_value) 
     except ValidationError as exc: 
      errors[field.field_name] = exc.detail 
     except DjangoValidationError as exc: 
      errors[field.field_name] = list(exc.messages) 
     except SkipField: 
      pass 
     else: 
      set_value(ret, field.source_attrs, validated_value) 

    if errors: 
     raise ValidationError(errors) 

    return ret 

正如你可以在這裏看到,首先,串行器調用field.run_validation方法,即用Django的字段校驗和他們提出DjangoValidationError例外,正因爲如此,您的驗證方法不會被調用。

+0

我在ModelSerializer中使用ModelViewSet可以在此階段配置什麼?我知道模型驗證是在rest框架驗證之前觸發的,這是我的問題...... –

+1

你可以使用'serializer.Meta.extra_kwargs'來爲這個字段設置'min_value'。我不確定,這會起作用,但你可以試試。另外,您可以嘗試在那裏設置驗證器,據我所知,它們會覆蓋默認驗證器 –

+0

謝謝,將extra_kwargs數量min_value設置爲None,禁用相應驗證! –