我刚刚创建了一个forms.models.BaseInlineFormSet来覆盖TabularInline模型的默认formset.我需要在formset验证(clean)中评估用户的组,因为某些组必须在范围(0,20)内写入一个数字.
我试过在init方法中从kwargs获取请求和用户,但是我无法获得引用.
这就是我现在拥有的:
class OrderInlineFormset(forms.models.BaseInlineFormSet): def __init__(self,*args,**kwargs): self.user = kwargs.pop('user') super(OrderInlineFormset,self).__init__(*args,**kwargs) def clean(self): # get forms that actually have valid data count = 0 for form in self.forms: try: if form.cleaned_data: count += 1 if self.user.groups.filter(name='Seller').count() == 1: if form.cleaned_data['discount'] > 20: raise forms.ValidationError('Not authorized to specify a discount greater than 20%') except AttributeError: # annoyingly,if a subform is invalid Django explicity raises # an AttributeError for cleaned_data pass if count < 1: raise forms.ValidationError('You need to specify at least one item') class OrderItemInline(admin.TabularInline): model = OrderItem formset = OrderInlineFormset
然后我在我的ModelAdmin中将它用作inlines = [OrderItemInline,].
不幸的是,self.user始终为None,因此我无法比较用户组,并且未应用过滤器.我需要过滤它,因为其他组应该能够指定任何折扣百分比.
解决方法
好吧,我在你的问题中认识到我的代码,所以我想我最好试着回答它.但我首先要说的是,该片段实际上仅用于验证formset中的最小数量的表单.您的用例不同 – 您想要检查每个表单中的内容.这应该在表单级别进行验证,而不是表单集.
也就是说,问题实际上并不在于您发布的代码,而是因为这只是其中的一部分.显然,如果你想在初始化表单或formset时从kwargs中获取用户,你需要确保用户实际上已经进入了初始化 – 默认情况下不是这样.
不幸的是,Django的管理员并没有给你一个适当的钩子来拦截初始化本身.但是你可以通过重写get_form函数并使用functools.partial来包装带有request参数的表单类来作弊(这段代码是合理的未经测试,但应该有效):
from functools import partial class OrderForm(forms.ModelForm): def __init__(self,**kwargs): self.user = kwargs.pop('user') super(OrderForm,**kwargs) def clean(self) if self.user.groups.filter(name='Seller').count() == 1: if self.cleaned_data['discount'] > 20: raise forms.ValidationError('Not authorized to specify a discount greater than 20%') return self.cleaned_data class MyAdmin(admin.ModelAdmin): form = OrderForm def get_form(self,request,obj=None,**kwargs): form_class = super(MyAdmin,self).get_form(request,obj,**kwargs) return functools.partial(form_class,user=request.user)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。