我正在尝试执行验证,以便在他是管理员时无法删除用户。因此,如果用户是管理员并且已被标记为删除,我想检查并引发错误。
这是我的内联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
块中的内容被执行但由于某种原因,从未引发此验证错误。有人可以向我解释原因吗?
更好的是,如果还有另一种更好的方法,请告诉我
答案 0 :(得分:7)
我找到的解决方案是clean
而不是InlineFormSet
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')
答案 1 :(得分:0)
尽管@domino的答案可能暂时有效,但“ kinda” 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('...')
答案 2 :(得分:0)
添加到多米诺骨牌的答案中:
在其他情况下,有时用户希望同时删除和添加对象,因此在这种情况下,删除应该没问题!
代码的优化版本:
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.")