Django:如何在管理表单中获取当前用户

Ber*_*ant 46 django django-forms django-admin username

在Django的ModelAdmin中,我需要显示根据用户拥有的权限定制的表单.有没有办法将当前用户对象放入表单类,以便我可以在其__init__方法中自定义表单?
我认为在本地线程中保存当前请求是可能的,但这将是我的最后手段,我想我认为这是一个糟糕的设计方法....

Jos*_*ker 54

以下是我最近为博客做的事情:

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
Run Code Online (Sandbox Code Playgroud)

我现在可以forms.ModelForm通过访问来访问我当前的用户self.current_user

编辑:这是一个老答案,最近看到它我意识到get_form应该修改方法:

    def get_form(self, request, *args, **kwargs):
         form = super(BlogPostAdmin, self).get_form(request, *args, **kwargs)
         form.current_user = request.user
         return form
Run Code Online (Sandbox Code Playgroud)

(注意添加*args)


sid*_*kap 22

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
Run Code Online (Sandbox Code Playgroud)

有关此方法的更多详细信息,请参阅此相关的Django文档


pti*_*tim 7

此用例记录在ModelAdmin.get_form

[...] 如果你想为超级用户提供额外的字段,你可以像这样交换不同的基本形式:

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)
Run Code Online (Sandbox Code Playgroud)

如果你只需要保存一个字段,那么你可以覆盖ModelAdmin.save_model

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)
Run Code Online (Sandbox Code Playgroud)


Ber*_*ant 5

我想我找到了一个适合我的解决方案:创建一个ModelFormDjango使用admin的formfield_for_db_field-method作为回调.
所以我在管理员中覆盖了这个方法,并将当前用户对象作为每个字段的属性传递(这可能不是最有效但对我来说比使用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
Run Code Online (Sandbox Code Playgroud)

现在,我可以使用以下内容访问表单中的当前用户对象__init__:

    current_user=self.fields['fieldname'].user
Run Code Online (Sandbox Code Playgroud)

  • 这是一个`AttributeError`:`kwargs.get('request',None).user` (2认同)