django admin-BaseInlineFormSet中的access request.user

django admin-BaseInlineFormSet中的access request.user,django,django-models,django-admin,django-forms,Django,Django Models,Django Admin,Django Forms,我刚刚创建了一个forms.models.BaseInlineFormSet来覆盖tablerinline模型的默认表单集。我需要在表单集验证(clean)中评估用户组,因为某些组必须写入一个范围(0,20)内的数字 我正在使用django admin自动生成接口 我已尝试在init方法中从kwargs获取请求和用户,但无法获取引用 这就是我现在拥有的: class OrderInlineFormset(forms.models.BaseInlineFormSet): def __ini

我刚刚创建了一个
forms.models.BaseInlineFormSet
来覆盖tablerinline模型的默认表单集。我需要在表单集验证(
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
类OrderInlineFormset(forms.models.BaseInlineFormSet):
定义初始化(self,*args,**kwargs):
self.user=kwargs.pop(“用户”)
super(OrderInlineFormset,self)。\uuuuu init\uuuu(*args,**kwargs)
def清洁(自清洁):
#获取实际具有有效数据的表单
计数=0
对于self.forms中的表单:
尝试:
如果form.u数据:
计数+=1
如果self.user.groups.filter(name='Seller').count()==1:
如果表单数据[“折扣”]>20:
raise forms.ValidationError('未授权指定大于20%的折扣')
除属性错误外:
#令人烦恼的是,如果子窗体无效,Django会显式地引发
#已清除数据的AttributeError
通过
如果计数小于1:
raise forms.ValidationError('您至少需要指定一项')
类OrderItemInline(管理列表行):
模型=订单项
formset=OrderInlineFormset
然后在我的ModelAdmin中将其用作
inlines=[OrderItemInline,]

不幸的是self.user总是
None
,因此我无法比较用户组,并且未应用筛选器。我需要筛选它,因为其他组应该能够指定任何折扣百分比


我该怎么办?如果您还需要ModelAdmin代码,我会发布它(我只是避免复制整个代码以避免混淆)。

好吧,我在您的问题中认识到我的代码,所以我想我最好尝试回答它。但我想说的是,首先,这个代码片段实际上只用于验证表单集中的最少数量的表单。您的用例是不同的-您希望检查每个表单中的某些内容。这应该通过表单级别的验证而不是表单集来完成

也就是说,问题不在于你发布的代码,而在于它只是其中的一部分。显然,如果您想在初始化表单或表单集时从kwargs获取用户,则需要确保用户实际被传递到该初始化中——默认情况下不是这样

不幸的是,Django的管理员并没有真正为您提供一个合适的钩子来拦截初始化本身。但是您可以通过重写
get\u form
函数并使用
functools.partial
用请求参数包装表单类来作弊(此代码未经测试,但应该可以正常工作):


这里有另一个不使用partials的选项。首先重写
tablerinline
类中的
get\u formset
方法

分配
request.user
或您需要在表单集中提供的任何额外变量,如下例所示:

class OrderItemInline(admin.TabularInline):
    model = OrderItem
    formset = OrderInlineFormset

    def get_formset(self, request, obj=None, **kwargs):  
       formset = super(OrderProductsInline, self).get_formset(request, obj, **kwargs)
       formset.user = request.user
       return formset
现在,用户可以在表单集中以
self.user

class OrderInlineFormset(forms.models.BaseInlineFormSet):

    def clean(self):
      print(self.user) # is available here 

很抱歉,我翻了这么一篇老文章,但我偶然发现了这个解决方案,在实现时我得到了:“functools.partial”对象没有属性“base\u fields”
class OrderInlineFormset(forms.models.BaseInlineFormSet):

    def clean(self):
      print(self.user) # is available here