如何检查Django(django-admin)中的值转换?

ha2*_*109 8 django django-forms django-admin

我有一个状态字段,其中包含3个值:挂起,激活和拒绝.如果我要更改状态值,我想要检查激活无法更改为待处理.我不想为此编写存储过程.我可以在保存前在Django中使用之前的值吗?

意味着新旧价值.

ha2*_*109 10

def clean_status(self):
    status = self.cleaned_data.get('status')
    if status == 'pending':
        if self.instance and self.instance.status == 'activated':
            raise forms.ValidationError('You cannot change activated to pending')

    return status
Run Code Online (Sandbox Code Playgroud)

此方法将添加到Form子类中.它的名字是clean_FIELD_NAME.

cleaned_data包含以前的值.存储新值self.instance.

或者,validate()可以将方法添加到forms.Field子类中.请参阅Django文档.


Dan*_*man 9

您可以在重写save方法中执行此操作.要记住的是Django模型实例不是实际的数据库对象,它们只是在加载时从那里获取它们的值.因此,在保存当前对象以获取现有值之前,您可以轻松返回数据库.

def save(self, *args, **kwargs):
    if self.status == 'pending':
         old_instance = MyClass.objects.get(pk=self.pk)
         if old_instance.status == 'activated':
              raise SomeError
     super(MyModel, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

除了引发异常之外,目前还没有向用户返回错误消息的好方法.目前正在进行Google Summer of Code项目以启用"模型验证",但这将在几个月内完成.

如果要在管理中执行类似操作,最好的方法是使用重写clean()方法定义自定义ModelForm .但是,这次是因为这是一个表单,您已经可以访问旧值而无需再次访问数据库.另一个好处是您可以向用户返回表单验证错误.

class MyModelForm(forms.ModelForm):

     class Meta:
          model = MyModel

    def clean_status(self):
        status = self.cleaned_data.get('status', '')
        if status == 'pending':
             if self.instance and self.instance.status == 'activated':
                  raise forms.ValidationError(
                      'You cannot change activated to pending'
                  )
         return status

 class MyModelAdmin(forms.ModelAdmin):
     form = MyModelForm
     model = MyModel
Run Code Online (Sandbox Code Playgroud)