2010-05-19 133 views
43

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

回答

49

这里是我最近的博客:

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 

我现在可以通过访问访问当前用户在我forms.ModelFormself.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 

(注意*args的加法)

5

我想我找到了一个解决方案,对我来说:创建一个ModelForm Django使用管理员的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 

现在我可以喜欢的东西访问当前用户对象的形式__init__

current_user=self.fields['fieldname'].user 
+2

这是一个'AttributeError':'kwargs.get( '请求',无).user' – hcalves 2012-03-19 19:07:34

20

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 

有关此方法的更多详细信息,请参阅this relevant Django documentation

+0

天才,我被卡在这个问题真正的努力 – bobleujr 2016-06-11 18:15:05

2

偶然发现了同样的事情,这是第一款谷歌结果我page.Dint帮助,位更多的谷歌搜索和工作!

这里是如何对我的作品(Django的1.7+):

class SomeAdmin(admin.ModelAdmin): 
    # This is important to have because this provides the 
    # "request" object to "clean" method 
    def get_form(self, request, obj=None, **kwargs): 
     form = super(SomeAdmin, self).get_form(request, obj=obj, **kwargs) 
     form.request = request 
     return form 

class SomeAdminForm(forms.ModelForm): 
    class Meta(object): 
     model = SomeModel 
     fields = ["A", "B"] 

    def clean(self): 
     cleaned_data = super(SomeAdminForm, self).clean() 
     logged_in_email = self.request.user.email #voila 
     if logged_in_email in ['[email protected]']: 
      raise ValidationError("Please behave, you are not authorised.....Thank you!!") 
     return cleaned_data 
+1

可爱的小解决办法,:) – 2018-01-16 10:24:15

+0

谢谢老兄! :) – NoobEditor 2018-01-19 05:50:05

1

就可以解决这个问题的另一种方法是使用Django钻营这不仅仅是请求对象加到表单清洁了一下模型。

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) 
0

这个用例是记录在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) 

如果你只需要保存一个字段,那么你可以只覆盖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)