首页 > 解决方案 > 如何验证用作外键的对象

问题描述

Django==2.2.5

您能帮我验证用作外键的对象是否未存档吗?

问题: parent_is_archived(obj) 接收 int 作为其参数。例如,1. 它不是我可以检查其字段的对象。并且没有这个 int 代表 pk 的模型的迹象。

也许我应该重新定义一些像 clean_fields 这样的方法?

class Level_1(models.Model):
    archived = models.BooleanField(default=False,
                                   verbose_name="Archived")

def parent_is_archived(obj):
    if ...:
        message = 'Parent object is archived'
        raise ValidationError(message)

class Level_2(models.Model):
    parent_level = models.ForeignKey(Level_1,
                                     on_delete=models.CASCADE,
                                     validators=[parent_is_archived])

标签: djangodjango-modelsdjango-validation

解决方案


您可以改写 save 方法:

class Level_2(models.Model):
    parent_level = models.ForeignKey(Level_1,
                                     on_delete=models.CASCADE,
                                     validators=[parent_is_archived])

   def save(self, *args, **kwargs):
      if self.parent_level.archived:
          raise Exception('....')
      super().save(*args, **kwargs)

或者,您也可以使用Model.clean()方法,您可以在其中放置限制:

class Level_2(models.Model):
    ...
    def clean(self):
      if self.parent_level.archived:
           raise ValidationError('...')

并用于instance.full_clean()调用 clean 方法。例如:

def some_view(request):
     form = LevelTwoForm(request.POST)
     if form.is_valid():
         instance = form.save(commit=False)
         instance.full_clean()
         instance.save()
     # rest of the code

推荐阅读