使用内联和表单类获得此管理类:
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.')
我需要使用外部方法对 InvoiceLineInlineFormset.clean 中每个 inlineform 中的_stock_code
值进行额外验证,如上图所示。但是外部方法需要请求对象作为参数才能正常运行。
是否可以将请求对象传递给clean方法?
答案 0 :(得分:1)
基础ModelAdmin
类有_create_formsets()
方法,它可以生成格式集:
def _create_formsets(self, request, obj, change):
"Helper function to generate formsets for add/change_view."
formsets = []
inline_instances = []
prefixes = {}
get_formsets_args = [request]
if change:
get_formsets_args.append(obj)
for FormSet, inline in self.get_formsets_with_inlines(*get_formsets_args):
prefix = FormSet.get_default_prefix()
prefixes[prefix] = prefixes.get(prefix, 0) + 1
if prefixes[prefix] != 1 or not prefix:
prefix = "%s-%s" % (prefix, prefixes[prefix])
formset_params = {
'instance': obj,
'prefix': prefix,
'queryset': inline.get_queryset(request),
}
if request.method == 'POST':
formset_params.update({
'data': request.POST,
'files': request.FILES,
'save_as_new': '_saveasnew' in request.POST
})
formsets.append(FormSet(**formset_params))
inline_instances.append(inline)
return formsets, inline_instances
正如您在formset_params
课程中使用方法&#39; request
参数扩展ModelAdmin
所示,您可以在formset的课程中保存额外的kwarg请求{ {1}}以后通过__init__()
在clean()
方法中使用它。
请注意,这不是最干净的解决方案,因为方法实现不允许轻松扩展kwargs,因此需要将整个方法移动到self.request
和任何Django&#39;更新这部分代码,您需要相应地更新您的方法。
答案 1 :(得分:0)
我有几乎相同的问题(如何从内联方法获取request.user的内容),我得到了对我有用的答案: Django: access to user info from admin.py for methods with no request object?
答案 2 :(得分:0)
这个问题很旧,但我将分享对我有用的解决方案 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
在表单集中,您可以使用self.request
访问请求对象。例如在clean方法中
class YourInlineFormset(forms.BaseInlineFormset):
def clean(self):
...
request = self.request