【问题标题】:validating a model in django-rest-framework在 django-rest-framework 中验证模型
【发布时间】:2015-12-10 23:00:32
【问题描述】:

我有一个带有自定义验证代码的 django 模型。当我使用 django-rest-framework 尝试创建/更新模型时,验证代码确实会运行,但不是输出一些带有错误内容的 JSON,而是失败并带有 ValidationError。为什么 django-rest-framework 没有捕捉到这个错误?

models.py

class MyModel(models.Model):
  is_default = models.BooleanField()
  type = models.CharField(max_length=64, choices=[("a","a"), ("b","b"), ("c","c")]

  def clean(self, *args, **kwargs):
    # there can be only 1 "default" model per type
    if self.is_default:
      other_models = MyModel.objects.filter(
        type=self.type, 
        default=True).exclude(pk=self.pk)
      if other_models.count() != 0:
        raise ValidationError({"default": "There can be only one default model per type.")
    super(MyModel, self).clean(*args, **kwargs)

serializers.py

class MyModelSerializer(ModelSerializer):

    class Meta:
        model = MyModel
        fields = ('id', 'default', 'type')

当我尝试发布 type="d" 的 JSON 数据时,我正确地得到以下响应:{ "type": ["this is not one of the valid choices"]}

但是当我尝试在 default=true 的情况下 POST JSON 数据(并且数据库中已经存在相同类型的默认模型)时,我只是得到了 ValidationError 而不是格式良好的 JSON。

【问题讨论】:

    标签: django django-models django-rest-framework


    【解决方案1】:

    第一个验证错误有效,因为 DRFs 引发了它。

    只有 DRF 的子类拥有 APIException 在框架内引发。所以你需要使用它的APIException 类来引发错误。

    例如,

    from rest_framework.exceptions import APIException
    
    class CustomException(APIException):
    
        status_code = 400
        default_detail = 'There can be only one default model per type.'
    

    然后你可以在你的模型中做到这一点。

     if other_models.count() != 0:
         raise CustomException()
    

    附带说明您为什么要尝试使用代码在模型上创建unique together 约束?您应该使用unique_together 在数据库级别执行此操作。

    例如,在模型上你可以做这样的事情......

     class Meta:
         unique_together = ("is_default", "type")
    

    一旦你运行了迁移,它会认为它们在一起时是独一无二的!

    【讨论】:

    • 关于 unique_together,这只是一些示例代码。严格来说,它不是 unique_together,因为我允许多个具有相同类型的模型,其中“默认”为 True。
    • 我刚刚尝试按照您的建议提出一个 django-rest-framework 特定错误。这确实有效,我将其标记为已接受的答案,谢谢。但是将 drf 代码与模型定义本身混合在一起似乎是错误的。
    • 然后在 DRFs 创建/更新方法中提升它,它的工作方式相同。或者在您看来 is_valid is etc.
    • 好建议。我将 create/update 包装在 try/catch 块中,并为每个 Django 错误返回一个 DRF 错误。感谢您的快速回复。
    猜你喜欢
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 2015-12-26
    • 2017-05-25
    • 1970-01-01
    • 2021-09-09
    相关资源
    最近更新 更多