加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

django admin – 访问BaseInlineFormSet中的request.user

发布时间:2020-12-20 11:22:22 所属栏目:Python 来源:网络整理
导读:我刚刚创建了一个forms.models.BaseInlineFormSet来覆盖TabularInline模型的默认formset.我需要在formset验证(clean)中评估用户的组,因为某些组必须在范围(0,20)内写入一个数字. 我正在使用django admin来自动生成界面. 我试过在init方法中从kwargs获取请求
我刚刚创建了一个forms.models.BaseInlineFormSet来覆盖TabularInline模型的默认formset.我需要在formset验证(clean)中评估用户的组,因为某些组必须在范围(0,20)内写入一个数字.

我正在使用django admin来自动生成界面.

我试过在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,因此我无法比较用户组,并且未应用过滤器.我需要过滤它,因为其他组应该能够指定任何折扣百分比.

我能怎么做?如果你还需要ModelAdmin代码,我将发布它(我只是避免复制整个代码以避免混淆).

解决方法

好吧,我在你的问题中认识到我的代码,所以我想我最好试着回答它.但我首先要说的是,该片段实际上仅用于验证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)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读