我正在尝试在实例方法中初始化MyModelAdmin类的form属性,如下所示:
class MyModelAdmin(admin.ModelAdmin):
def queryset(self, request):
MyModelAdmin.form = MyModelForm(request.user)
我的目标是根据当前会话自定义MyModelForm
的编辑表单。然而,当我尝试这个时,我不断收到错误(如下所示)。这是将会话数据传递给ModelForm的适当位置吗?如果是,那么可能导致此错误的原因是什么?
TypeError在......
异常类型:TypeError
异常值:issubclass()arg 1必须是类
异常位置:新,第185行中的/usr/lib/pymodules/python2.6/django/forms/models.py
答案 0 :(得分:1)
理论上,您可以覆盖ModelAdmin的get_form
方法:
# In django.contrib.admin.options.py
def get_form(self, request, obj=None, **kwargs):
"""
Returns a Form class for use in the admin add view. This is used by
add_view and change_view.
"""
if self.declared_fieldsets:
fields = flatten_fieldsets(self.declared_fieldsets)
else:
fields = None
if self.exclude is None:
exclude = []
else:
exclude = list(self.exclude)
exclude.extend(kwargs.get("exclude", []))
exclude.extend(self.get_readonly_fields(request, obj))
# if exclude is an empty list we pass None to be consistant with the
# default on modelform_factory
exclude = exclude or None
defaults = {
"form": self.form,
"fields": fields,
"exclude": exclude,
"formfield_callback": curry(self.formfield_for_dbfield, request=request),
}
defaults.update(kwargs)
return modelform_factory(self.model, **defaults)
请注意,这会返回表单类而不是表单实例。
答案 1 :(得分:1)
如果有些新手,就像我一样,经过这里: 我不得不定义:
class XForm(forms.ModelForm):
request=None
然后在上一篇文章末尾
mfc=modelform_factory(self.model, **defaults)
self.form.request=request #THE IMPORTANT statement
return mfc
答案 2 :(得分:1)
结合Izz ad-Din Ruhulessin's answer和suggestion by Cikić Nenad中的好主意,我最终得到了一个非常棒的简洁解决方案:
class CustomModelAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
self.form.request = request #so we can filter based on logged in user for example
return super(CustomModelAdmin, self).get_form(request,**kwargs)
然后只需为modeladmin设置自定义表单,如:
form = CustomAdminForm
在自定义的modelform类访问请求中,如:
self.request #do与表格相关的请求
答案 3 :(得分:0)
我使用queryset fot过滤记录,也许这个例子可以帮助你:
.....
.....
def queryset(self, request):
cuser = User.objects.get(username=request.user)
qs = self.model._default_manager.get_query_set()
ordering = self.ordering or () # otherwise we might try to *None, which is bad ;)
if ordering:
qs = qs.order_by(*ordering)
qs = qs.filter(creator=cuser.id)
return qs
答案 4 :(得分:0)
以下是nemesisfixx解决方案的生产/线程安全变体:
def get_form(self, request, obj=None, **kwargs):
class NewForm(self.form):
request = request
return super(UserAdmin, self).get_form(request, form=NewForm, **kwargs)