2010-08-01 188 views
0

我有一個Django模型如下Django管理處理一對多關係

class Project(models.Model) 
     name=models.CharField(max_length=200) 

class Application(models.Model) 
     proj=models.ForeignKey(Project, null=True, blank=True) 

我需要修改該項目的管理形式,能夠將多個應用程序分配到的項目,所以在管理。 PY我已經創建了項目的ModelAdmin類如下

class ProjectAdmin(ModelAdmin) 
     form=projectForm 
     project_apps=[] 

和項目形式如下

class ProjectForm(forms.ModelForm): 
    class Meta: 
     model = Project 

    project_apps =forms.ModelMultipleChoiceField(queryset=Application.objects.all(),required=False,) 
def __init__(self, *args, **kwargs): 
    super(ProjectForm, self).__init__(*args, **kwargs) 
    if self.instance.id is not None: 
     selected_items = [ values[0] for values in Application.objects.filter(project=self.instance) ] 
     self.fields['project_apps'].initial = selected_items 

def save(self,commit=True): 
    super(ProjectForm,self).save(commit) 
    return self.instance 

通過這樣做我在創建/編輯項目表單中有多個選擇。 我需要的是覆蓋保存方法以保存所選應用程序中項目的引用?

我怎樣才能得到選定的應用程序?

+0

爲什麼你不使用內聯管理員? – 2010-08-01 12:13:04

+0

我用它,但它增加了3個組合框,我希望它在多個選擇列表 – Fanooos 2010-08-01 13:33:48

回答

0

不完全確定你想要做什麼,但也許這?現在

def save(self,commit=True): 
    kwargs.pop('commit') # We're overriding this with commit = False 
    super(ProjectForm,self).save(commit) 
    if self.instance: 
     for a in self.cleaned_data['project_apps']: 
      a.proj = self.instance 
      a.save() 
    return self.instance 

,我不記得,如果在這種情況下,self.cleaned_data['project_apps']實際上將包含Application對象與否的列表。我懷疑這會,但如果沒有這個功能將採取照顧:

def clean_project_apps(self): 
    app_list = self.cleaned_data['project_apps'] 
    result = [] 
    for a in app_list: 
     try: 
      result.append(Application.objects.get(pk=a) 
     except Application.DoesNotExist: 
      raise forms.ValidationError("Invalid application record") # to be safe 
    return result 

總之,我覺得這種形式是一個壞主意,但因爲基本上這裏發生的一切是你展示所有的申請記錄沒有意義,因爲其中大多數將與其他項目相關聯。

哦,哦,哦!剛注意到你想讓它顯示在多選列表中!

你(可能)這樣做是錯誤

多選擇的手段,這是不是一個一對多的關係。 這是一個多對多的關係。

這就是你想要做的,容易pe,,不需要任何自定義表格或任何東西

class Project(models.Model) 
     name=models.CharField(max_length=200) 
     project_apps = models.ManyToMany('Application', null=True, blank=True) 

class Application(models.Model) 
     # nothing here (NO foreign key, you want more than one App/Proj and vice versa) 

指示這是Project中的多對多字段,將自動在admin中創建多選框。達達!

+0

我只想補充說,如果不是,真的希望它是一對多的關係,那麼多選框是要使用的界面錯誤。這就像製造汽車一樣,向右轉意味着加速,而向左轉意味着減速。多選字段意味着「查看,對於任何給定的記錄,您可以選擇一個或多個這些選項!」這是一種多對多的關係。如果你的意思是「這些是這個主要項目的潛在孩子」,那麼這是不正確的界面,雖然你個人不喜歡它,但內聯管理員是正確的界面。 – 2010-08-02 17:01:12