2010-05-19 134 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)