2015-06-20 52 views
2

我對我的第一個Django項目工作的ModelForm預填充複選框。Django的:使用自定義查詢

我有兩個模型之間的許多一對多的關係:用戶和項目。 雖然更新項目,我想表明與添加新成員,刪除現有成員字段根據當前工程用戶正確選擇形式。

這裏是我試過到目前爲止:

  1. 從URL
  2. 獲取當前項目通過當前項目,以標準格式
  3. 形式,自定義查詢集運行。

問題:不顯示查詢集的結果。

在views.py

類UpdateProject(LogInRequiredMixin,更新視圖):

""" Class to Edit Project. 
""" 

form_class = ProjectUpdateForm 
template_name = 'project/create.html' 

def get_object(self): 
    self.project_instance = models.Project.objects.get(pk=self.kwargs['project']) 
     return self.project_instance 

def get_form_kwargs(self): 
    kwargs = super(UpdateProject, self).get_form_kwargs() 
    kwargs.update({'project': self.project_instance}) 
    return kwargs 

對於形式 ProjectUpDateForm

class ProjectUpdateForm(forms.ModelForm): 
    """ Form to update Project Field. """ 

    add_member = forms.CharField(label="Add New Members", widget=forms.CheckboxSelectMultiple) 
    del_member = forms.CharField(label="Remove Members", widget=forms.CheckboxSelectMultiple) 

    def __init__(self, *args, **kwargs): 
     self.project = kwargs.pop('project') 
     super(ProjectUpdateForm, self).__init__(*args, **kwargs) 
     print MyUser.objects.exclude(pk__in=self.project.members.all()) 
     print MyUser.objects.filter(pk__in=self.project.members.all()) 

     self.fields['add_member'].queryset = MyUser.objects.exclude(pk__in=self.project.members.all()) 
     self.fields['del_member'].queryset = MyUser.objects.filter(pk__in=self.project.members.all()) 

    # Rest of Class Logic 

打印對帳單的工作,並返回正確的結果,但我無法在應用中查看結果。它顯示空白。

此外,我想知道他們更容易達到相同的方式嗎? (在我看來,我不應該明確地傳遞項目?)

+0

這兩種形式的Meta類是什麼? – Pcriulan

+0

@Pcriulan 表單 類元: 模型=項目 欄= [「標題」,「描述」] 對於View,我沒有使用元 –

+0

好了,所以你需要添加你的自定義字段中的字段: fields = ['title','description','add_member','del_member']。這樣你就可以告訴django瞭解這些領域。 – Pcriulan

回答

1

至於我能找到的,這解決了

多到許多領域明確雛型當添加的問題,你期望多重響應,所使用的模塊應該是ModelMultipleChoiceField

另外,由於我們超越了init方法,並且有一個查詢集,所以定義它的最好的地方是在init中。

最終形式代碼:

class ProjectUpdateForm(forms.ModelForm): 
    """ Form to update Project Field. """ 


    def __init__(self, *args, **kwargs): 
     self.project = kwargs.pop('project') 
     super(ProjectUpdateForm, self).__init__(*args, **kwargs) 

     self.fields['add_member'] = forms.ModelMultipleChoiceField(label="Add New members", 
                    widget=forms.CheckboxSelectMultiple, 
                    queryset=MyUser.objects.exclude(pk__in=self.project.members.all())) 
     self.fields['del_member'] = forms.ModelMultipleChoiceField(label="Remove Members", 
                    widget=forms.CheckboxSelectMultiple, 
                    queryset=MyUser.objects.filter(pk__in=self.project.members.all())) 

    class Meta: 
     model = Project 
     fields = ['title', 'description'] 

    #Rest of Form Logic 

這應該這樣做!我們並不需要完全初始化過來寫(如果查詢需要通過


可能是有人

萬一,我們已經在我們的模型中定義的字段有用參數)

我們可以通過 self.fields [「FIELD_NAME」]定義它查詢集在初始化。查詢集=邏輯

而在元ç添加插件姑娘。


PS:我仍然在尋找更簡單的方法來訪問當前對象,而不是通過查看被顯式傳遞,但!

0

我瞭解添加add_memberdel_member操作的想法。

但是,爲什麼你不能僅僅使用一個ModelMultipleChoiceField來顯示可能在項目中的每個用戶,只是複選框顯示已經參與項目的用戶?

我沒有測試這一點,但它可能看起來像:

class ProjectForm(forms.ModelForm): 

    class Meta: 
     model = Project 
     fields = ['title', 'description'] 

    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 
     current_members = self.instance.members.all() # What are the current members? 
     possible_members = User.objects.all() # Change this if you want a different set of users to add. 
     self.fields['members'] = forms.ModelMultipleChoiceField(label="Members", 
                   widget=forms.CheckboxSelectMultiple, 
                   queryset=possible_members, 
                   initial=current_members, 
                   required=False) # If it can be empty 

    def save(self, commit=True): 
     instance = super().save(commit=False) # Saving with commit=False add a save_m2m method to self 
     if commit: 
      instance.members.clear()   # We delete every member 
      for m in self.cleaned_data.get('members'): # We them add again every checked user as member at form submission 
       instance.members.add(m) 
      instance.save()     # We save the instance 
      self.save_m2m()     # We also save the changes in the M2M relationship. 
      return instance 

訣竅是檢索用戶是目前該項目實例的成員和預檢覆選框,以顯示他們在所有用戶的整個列表(勾選:用戶誰是會員,未勾選:不是會員的用戶)。

因此,如果您選中一個框,則添加該用戶,如果取消選中該框,則會將其從成員列表中刪除。