Django:如何在管理表单中获取当前用户?
在Django的Django:如何在管理表单中获取当前用户?,django,django-forms,django-admin,Django,Django Forms,Django Admin,在Django的ModelAdmin中,我需要显示根据用户权限定制的表单。是否有一种方法可以将当前用户对象放入表单类中,以便我可以在其\uuuu init\uuuu方法中自定义表单 我认为在本地线程中保存当前请求是可能的,但这将是我最后的选择,因为我认为这是一种糟糕的设计方法。我认为我找到了一个适合我的解决方案:创建模型表单Django使用admin的formfield\u for_db\u field-方法作为回调。 因此,我在我的管理中覆盖了此方法,并将当前用户对象作为属性传递给每个字段(这
ModelAdmin
中,我需要显示根据用户权限定制的表单。是否有一种方法可以将当前用户对象放入表单类中,以便我可以在其\uuuu init\uuuu
方法中自定义表单
我认为在本地线程中保存当前请求是可能的,但这将是我最后的选择,因为我认为这是一种糟糕的设计方法。我认为我找到了一个适合我的解决方案:创建
模型表单Django使用admin的formfield\u for_db\u field
-方法作为回调。
因此,我在我的管理中覆盖了此方法,并将当前用户对象作为属性传递给每个字段(这可能不是最有效的,但对我来说比使用threadlocals更干净:
def formfield_for_dbfield(self, db_field, **kwargs):
field = super(MyAdmin, self).formfield_for_dbfield(db_field, **kwargs)
field.user = kwargs.get('request', None).user
return field
现在,我可以通过以下方式访问表单\uuuu init\uuuu
中的当前用户对象:
current_user=self.fields['fieldname'].user
以下是我最近为一个博客所做的:
class BlogPostAdmin(admin.ModelAdmin):
form = BlogPostForm
def get_form(self, request, **kwargs):
form = super(BlogPostAdmin, self).get_form(request, **kwargs)
form.current_user = request.user
return form
现在,我可以通过访问self.current\u user
EDIT:这是一个古老的答案,最近我发现get\u form
方法应该修改为:
def get_form(self, request, *args, **kwargs):
form = super(BlogPostAdmin, self).get_form(request, *args, **kwargs)
form.current_user = request.user
return form
(注意添加了*args
)Joshmaker的答案在Django 1.7上对我不起作用。以下是我为Django 1.7所做的:
class BlogPostAdmin(admin.ModelAdmin):
form = BlogPostForm
def get_form(self, request, obj=None, **kwargs):
form = super(BlogPostAdmin, self).get_form(request, obj, **kwargs)
form.current_user = request.user
return form
有关此方法的更多详细信息,请参见偶然发现了相同的东西,这是我页面上的第一个谷歌结果。Dint帮助了我,更多的谷歌搜索和工作
以下是它对我的作用(django 1.7+):
解决此问题的另一种方法是使用Django Curring,这比仅将请求对象附加到表单模型更简洁
from django.utils.functional import curry
class BlogPostAdmin(admin.ModelAdmin):
form = BlogPostForm
def get_form(self, request, **kwargs):
form = super(BlogPostAdmin, self).get_form(request, **kwargs)
return curry(form, current_user=request.user)
这还有一个额外的好处,那就是使表单上的init方法更加清晰,因为其他人会理解它是作为kwarg传递的,而不仅仅是在初始化之前随机附加到类对象的属性
class BlogPostForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.current_user = kwargs.pop('current_user')
super(BlogPostForm, self).__init__(*args, **kwargs)
此用例记录在
[…]如果您想为超级用户提供额外的字段,可以使用不同的基本形式进行交换,如下所示:
如果您只需要保存一个字段,那么您可以直接重写
这是一个AttributeError
:kwargs.get('request',None).user
如果form=BlogPostForm
,那么get\u form
实际返回什么?BlogPostForm或BlogPostAdmin父类的ModelForm…?如果使用get\u form,BlogPostForm将如何使用?这不是要在form类而不是特定的表单实例上设置用户吗?这似乎有点危险…我喜欢但遗憾的是,这不起作用,因为下游代码需要一个表单类而不是curry函数。这样做会导致以下错误“'function'对象没有属性'base_fields'”。是否可以直接将其添加到kwargs?
class BlogPostForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.current_user = kwargs.pop('current_user')
super(BlogPostForm, self).__init__(*args, **kwargs)
class MyModelAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
if request.user.is_superuser:
kwargs['form'] = MySuperuserForm
return super().get_form(request, obj, **kwargs)
from django.contrib import admin
class ArticleAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.user = request.user
super().save_model(request, obj, form, change)