有没有办法在 django 内联表单集清理方法中访问请求对象?

Sen*_* H. 2 django django-forms

得到了这个带有内联和表单类的管理类:

class InvoiceAdmin(admin.ModelAdmin):
    ....
    inlines = [InvoiceLineInline, ]
    form = InvoiceForm
    ....

class InvoiceForm(forms.ModelForm):
    ....
    def clean():
        ....

    class Meta:
        model = Invoice
        exclude = []


class InvoiceLineInline(admin.TabularInline):
    model = InvoiceLine
    formset = InvoiceLineInlineFormset
    extra = 1


class InvoiceLineInlineFormset(forms.models.BaseInlineFormSet):
    def clean(self):
        super(InvoiceLineInlineFormset, self).clean()

        count = 0
        for form in self.forms:
            if not hasattr(form, 'cleaned_data'):
                continue

            data = form.cleaned_data
            try:
                if data:
                    count += 1
                else:
                    continue
            except AttributeError:
                pass

            if Decimal(data.get('quantity', 0)) <= 0:
                raise forms.ValidationError("Amount should be greater than 0.")
            ******************************************************
            _stock_code = data.get('stock_code', None)
            if not len(fetch_stocks_from_connector(request, stock_code=_stock_code)):
                raise forms.ValidationError("{} Stock code does not exist at connector.".format(_stock_code))
            ******************************************************    
        if count < 1:
            raise forms.ValidationError('Need one line at least.')
Run Code Online (Sandbox Code Playgroud)

我需要使用外部方法对InvoiceLineInlineFormset.clean_stock_code每个内联表单中的值进行额外验证,如上面星号线之间所示。但外部方法需要请求对象作为参数才能正常运行。

是否可以将请求对象传递给 clean 方法?

小智 6

这个问题很旧,但我将分享对我有用的解决方案 ModelAdmin 有一个 get_formset 方法。你可以这样扩展它

class YourAdminInline(admin.TabularInline):
    model = YourModel
    formset = YourInlineFormSet

    def get_formset(self,request,obj=None,**kwargs):
        formset = super(YourAdminInline,self).get_formset(request,obj,**kwargs)
        formset.request = request
        return formset
Run Code Online (Sandbox Code Playgroud)

在您的表单集中,您可以使用 访问请求对象self.request。例如在 clean 方法中

class YourInlineFormset(forms.BaseInlineFormset):
    def clean(self):
        ...
        request = self.request
Run Code Online (Sandbox Code Playgroud)