【问题标题】:Validating delete on django-admin inline forms在 django-admin 内联表单上验证删除
【发布时间】:2011-05-17 07:21:18
【问题描述】:

我正在尝试执行验证,如果用户是管理员,您将无法删除他。因此,如果有管理员用户被标记为删除,我想检查并提出错误。

这是我的内联ModelForm

class UserGroupsForm(forms.ModelForm):
    class Meta:
        model = UserGroups

    def clean(self):
        delete_checked = self.fields['DELETE'].widget.value_from_datadict(
            self.data, self.files, self.add_prefix('DELETE'))
        if bool(delete_checked):
            #if user is admin of group x
            raise forms.ValidationError('You cannot delete a user that is the group administrator')

        return self.cleaned_data

if bool(delete_checked): 条件返回 true,if 块内的内容被执行,但由于某种原因,从未引发此验证错误。有人可以解释一下为什么吗?

如果有其他更好的方法可以做到这一点,请告诉我

【问题讨论】:

    标签: django validation django-admin django-forms


    【解决方案1】:

    我找到的解决方案是在InlineFormSet 中使用clean 而不是ModelForm

    class UserGroupsInlineFormset(forms.models.BaseInlineFormSet):
    
        def clean(self):
            delete_checked = False
    
            for form in self.forms:
                try:
                    if form.cleaned_data:
                        if form.cleaned_data['DELETE']:
                            delete_checked = True
    
                except AttributeError:
                    pass
    
            if delete_checked:
                raise forms.ValidationError(u'You cannot delete a user that is the group administrator')
    

    【讨论】:

      【解决方案2】:

      虽然@domino 的答案现在可能有效,但“有点”recommended approach 是将formset 的self._should_delete_form(form) 函数与self.can_delete 一起使用。

      还有调用super().clean() 来执行标准内置验证的问题。所以最终的代码可能是这样的:

      class UserGroupsInlineFormset(forms.models.BaseInlineFormSet):
          def clean(self):
              super().clean()
              if any(self.errors):
                  return  # Don't bother validating the formset unless each form is valid on its own
              for form in self.forms:
                  if self.can_delete and self._should_delete_form(form):
                      if <...form.instance.is_admin...>:
                          raise ValidationError('...')
      

      【讨论】:

        【解决方案3】:

        添加到多米诺骨牌的答案:

        在其他一些场景中,有时用户想同时删除添加对象,所以在这种情况下删除应该没问题!

        优化版代码:

        class RequiredImageInlineFormset(forms.models.BaseInlineFormSet):
            """ Makes inline fields required """
        
            def clean(self):
                # get forms that actually have valid data
                count = 0
                delete_checked = 0
                for form in self.forms:
                    try:
                        if form.cleaned_data:
                            count += 1
                            if form.cleaned_data['DELETE']:
                                delete_checked += 1
                            if not form.cleaned_data['DELETE']:
                                delete_checked -= 1
                    except AttributeError:
                        # annoyingly, if a subform is invalid Django explicity raises
                        # an AttributeError for cleaned_data
                        pass
        
                # Case no images uploaded
                if count < 1:
                    raise forms.ValidationError(
                        'At least one image is required.')
        
                # Case one image added and another deleted
                if delete_checked > 0 and ProductImage.objects.filter(product=self.instance).count() == 1:
                    raise forms.ValidationError(
                        "At least one image is required.")
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-04-09
          • 2012-11-11
          • 2014-08-17
          • 2014-05-09
          • 1970-01-01
          • 2016-03-15
          • 1970-01-01
          • 2011-07-11
          相关资源
          最近更新 更多