Django管理员处理一对多的关系

时间:2010-08-01 08:30:45

标签: django django-admin django-forms

我有一个django模型如下

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

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

我需要修改项目的管理表单才能为项目分配多个应用程序,所以在admin.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

通过这样做,我在创建/编辑项目表单中有一个多选。 我需要的是覆盖save方法以保存所选应用程序中项目的引用?

如何获取所选应用程序????

1 个答案:

答案 0 :(得分: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

总而言之,我认为这种形式是一个坏主意,因为基本上这里发生的是你正在显示所有的应用程序记录,这是没有意义的,因为大多数将与其他项目相关联。

哦,哦,哦!刚刚注意到你希望它出现在多选列表中!

你(可能)做错了

多重选择意味着这不是一对多的关系。 这是一种多对多的关系。

这就是你想做的事情,轻松自如,不需要任何自定义表格或任何

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中创建多个选择框。塔达!