1

我已經重寫我的模型的默認管理器,以顯示只允許項目評估查詢集,根據登錄的用戶(一種特定對象的權限):Django的:使ModelChoiceField在運行時

class User_manager(models.Manager): 
    def get_query_set(self): 
     """ Filter results according to logged user """ 
     #Compose a filter dictionary with current user (stored in a middleware method) 
     user_filter = middleware.get_user_filter() 
     return super(User_manager, self).get_query_set().filter(**user_filter) 

class Foo(models.Model): 
    objects = User_manager() 
    ... 

這樣,每當我用Foo.objects,當前用戶檢索和過濾器被應用到默認查詢集,以顯示只允許記錄。

然後,我有一個ForeignKey到富的典範:

class Bar(models.Model): 
    foo = models.ForeignKey(Foo) 

class BarForm(form.ModelForm): 
    class Meta: 
     model = Bar 

當我撰寫BarForm我希望只看到filteres富實例,但沒有應用濾鏡。我認爲這是因爲queryset在Django啓動時被計算和緩存,當沒有用戶登錄並且沒有應用過濾器時。

有沒有做的Django evalutate在運行時的ModelChoice查詢集,而不必使其在表單定義明確的方法? (儘管所有的性能問題...)

編輯 我發現那裏的查詢集進行評估(Django的\ DB \型號\域\ related.py:887):

def formfield(self, **kwargs): 
    db = kwargs.pop('using', None) 
    defaults = { 
     'form_class': forms.ModelChoiceField, 
     'queryset': self.rel.to._default_manager.using(db).complex_filter(self.rel.limit_choices_to), 
     'to_field_name': self.rel.field_name, 
    } 
    defaults.update(kwargs) 
    return super(ForeignKey, self).formfield(**defaults) 

任何提示?

+0

顯示一些代碼! – 2011-03-18 11:58:34

+0

ModelChoice的查詢集已經是懶惰,probabily你某處評估查詢集,呈現出一些代碼(經理+的形式實現)將幫助:) – 2011-03-18 13:10:35

+0

我已經添加了代碼。把一個斷點定製經理裏面,我看到get_queryest」在Django的啓動只計算(當消息‘ – Don 2011-03-18 14:44:28

回答

1

我使用自定義窗體的初始化

class BT_Form(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(BT_Form, self).__init__(*args, **kwargs) 

     #prepare new values 
     cities = [(u'',u'------')] #default value 
     cities.extend([ 
      (
       c.pk, 
       c.__unicode__() 
      ) for c in City.objects.filter(enabled=True).all() 
     ]) 

     self.fields['fly_from_city'].choices = cities #renew values 
+0

或初始化中‘的runserver’顯示驗證模型...') - BT_Form.base_fields [’fly_from_city '] .queryset = ... – 2011-11-08 18:01:50

+0

和after - super(.. – 2011-11-08 18:35:36

0

沒辦法:我不得不重寫查詢集定義(在啓動時計算)

2

有完全相同這個問題 - 填充選擇所需形式與用戶對象從一個組,但fun_vit的回答是不正確的(至少對於Django 1.5)

首先,你不想覆蓋字段['somefield']。選擇對象 - 它是一個ModelChoiceIterator對象,不是一個查詢集。其次,在django.forms.BaseForm評論警告你以防覆蓋base_fields:

# The base_fields class attribute is the *class-wide* definition of 
    # fields. Because a particular *instance* of the class might want to 
    # alter self.fields, we create self.fields here by copying base_fields. 
    # Instances should always modify self.fields; they should not modify 
    # self.base_fields. 

這爲我工作(Django的1.5):

class MyForm(ModelForm): 
    users = ModelMultipleChoiceField(queryset=User.objects.none()) 

    def __init__(self, *args, **kwargs): 
     super(MyForm, self).__init__(*args,**kwargs) 

     site = Site.objects.get_current() 
     self.fields['users'].queryset = site.user_group.user_set.all() 

    class Meta: 
     model = MyModel 
+0

請注意,您也可以通過創建新的字段對象來替換整個self.fields ['users']對象。 – wjin 2013-09-29 20:06:00