带有显示所有可能对象的 ManyToManyField 的 Django ModelForm

Django ModelForm with ManyToManyField showing all possible objects

我需要你的帮助。我试图找到解决方案几天,但到目前为止没有运气。这是设置:

可以有多个项目,任务和人可以分配给项目,一个人可以分配给多个任务,同一个任务可以分配给不同的人。目前没有问题...

当我尝试显示特定任务(分配给 1 个项目)的表单时,它会显示所有项目的所有人员,但我只需要查看与所选任务关联的项目中的人员。

非常感谢您!

class Project(models.Model):
    project_name = models.CharField(max_length=50)

    def __str__(self):
        return self.project_name

class Person(models.Model):
    person_name = models.CharField('Person Name',max_length=50)
    project = models.ForeignKey(Project, on_delete=models.CASCADE)

    def __str__(self):
        return self.person_name 

class Task(models.Model):
    task_name = models.CharField('Task Name',max_length=50)
    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    people = models.ManyToManyField(Person)

    def __str__(self):
        return self.task_name 

class TaskForm(forms.ModelForm):
    class Meta:
        model = Task
        fields = ('task_name','people',)

策略:在表单实例化时将查询集动态限制为允许的People对象。

我也不会省略表单中的 project 字段,因为保存表单时需要它。更好的方法是隐藏该字段并将 initial value dynamically 传递给它。

class TaskForm(forms.ModelForm):
    class Meta:
        model = Task
        widgets = {'project': forms.HiddenInput()}

    def __init__(self, *args, **kwargs):
        # Form requires a project, so assert it is instantiated with a valid initial value:
        assert 'initial' in kwargs and 'project' in kwargs['initial'] and type(kwargs['initial']['project'] is Project)
        super(TaskForm, self).__init__(*args, **kwargs)
        project = kwargs['initial']['project']
        self.fields['people'].queryset = Person.objects.filter(project=project)

# Instantiate the form. 'my_project' has to be a Project-instance
my_taskform = TaskForm(initial={'project': my_project})