Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django:如何在管理表单中获取当前用户?_Django_Django Forms_Django Admin - Fatal编程技术网

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-方法作为回调。 因此,我在我的管理中覆盖了此方法,并将当前用户对象作为属性传递给每个字段(这

在Django的
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)