2010-08-01 143 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