Django ModelMultipleChiceField用于另一个型号';It’多对多

Django ModelMultipleChiceField用于另一个型号';It’多对多,django,django-models,django-forms,Django,Django Models,Django Forms,我正在开发一个DIY应用程序(Django 1.5),我遇到了一个障碍。涉及的主要模型有指南,工具,项目,步骤。一个指南可以有许多工具和项目,一个工具或项目可以属于许多指南。步骤也是如此——它可以有许多工具和项目,一个工具或项目可以属于许多步骤。向导有许多步骤,步骤属于向导 指南多对多项目 指南多对多工具 指南一对多步骤 步骤多对多项目 步骤多对多工具 路障 在向导级别,我希望工具和项目选项是无限的。但在步骤级别,我希望工具和项目选项仅限于分配给它所属的指南的选项。基本上,当创建/编辑一个步骤时

我正在开发一个DIY应用程序(Django 1.5),我遇到了一个障碍。涉及的主要模型有
指南
工具
项目
步骤
。一个指南可以有许多工具和项目,一个工具或项目可以属于许多指南。步骤也是如此——它可以有许多工具和项目,一个工具或项目可以属于许多步骤。向导有许多步骤,步骤属于向导

指南多对多项目

指南多对多工具

指南一对多步骤

步骤多对多项目

步骤多对多工具

路障

在向导级别,我希望工具和项目选项是无限的。但在步骤级别,我希望工具和项目选项仅限于分配给它所属的指南的选项。基本上,当创建/编辑一个步骤时,我想列出指南中所有可用工具和项目的复选框。用户选择当前步骤所需的内容。每个步骤都有不同的工具和项目组合(因此需要复选框)

我发现了步骤的ModelForm类的
modelmultipechoicefield
。在那里我可以指定查询集但是,我如何获得对向导模型实例的访问权以检索其工具和项目,以便正确生成选择?我希望提供类似于您在视图中所做的查询

Guide.objects.get(pk=n).tools.all()
Guide.objects.get(pk=n).items.all()
如何通过
modelmultipechoicefield
实现这一点?我希望我能解释清楚这一点

提前感谢您的帮助

class Tool(models.Model):
    name = models.CharField(max_length=100)
    ...


class Item(models.Model):
    name = models.CharField(max_length=100)
    ...


class Guide(models.Model):
    models.CharField(max_length=100)
    description = models.CharField(max_length=500)
    tools = models.ManyToManyField(Tool, null=True, blank=True)
    items = models.ManyToManyField(Item, null=True, blank=True)
    ...


class Step(models.Model):
    title = models.CharField(max_length=100)
    body = models.TextField()
    guide = models.ForeignKey(Guide)
    tools = models.ManyToManyField(Tool, null=True, blank=True)
    items = models.ManyToManyField(Item, null=True, blank=True)
编辑:5/2 在进一步阅读之后,我似乎必须重写
modelmultipechoicefield
\uuuu init\uuuu
方法,在这里我获得了对
self.instance
的引用,允许我创建类似于
self.instance.guide.tools.all()
self.instance.guide.items.all()的查询。然后通过
字段['field\u name']
创建字段


我现在在工作,所以我要到今晚晚些时候才能尝试。我将报告我的发现。

我最后做的是以下几点。我在ModelForm类中定义了一个方法,用于创建
modelmultipechoicefield
。原因是在请求创建步骤页面时,没有与该步骤相关联的指南,直到您保存(POST…假设验证成功)。但我确实可以访问指南中的slug字段,该步骤将为其创建。我从URL获取if。而slug字段在我的应用程序中是独一无二的。因此,我通过我创建的新方法将slug从我的视图传递到表单。从那里,我可以获得分配给指南的工具,并在我的模板中的表单上提供这些选项

forms.py

class NewStepForm(forms.ModelForm):
    ...
    def create_tools_field(self, slug):
        self.fields['tools'] = forms.ModelMultipleChoiceField(
            queryset=Guide.objects.get(slug=slug).tools.all(),
            widget=forms.CheckboxSelectMultiple(attrs={'class': 'unstyled'})
        )
    ...
class NewStepView(View):

    form_class = NewStepForm
    initial = {'key': 'value'}
    template_name = "guides/guide_step_new.html"

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(NewStepView, self).dispatch(*args, **kwargs)

    def get(self, request, *args, **kwargs):
        slug = kwargs.get('slug')
        form = self.form_class(initial=self.initial)
        form.create_tools_field(slug)
        return render(request,  self.template_name, {'form': form})
视图.py

class NewStepForm(forms.ModelForm):
    ...
    def create_tools_field(self, slug):
        self.fields['tools'] = forms.ModelMultipleChoiceField(
            queryset=Guide.objects.get(slug=slug).tools.all(),
            widget=forms.CheckboxSelectMultiple(attrs={'class': 'unstyled'})
        )
    ...
class NewStepView(View):

    form_class = NewStepForm
    initial = {'key': 'value'}
    template_name = "guides/guide_step_new.html"

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(NewStepView, self).dispatch(*args, **kwargs)

    def get(self, request, *args, **kwargs):
        slug = kwargs.get('slug')
        form = self.form_class(initial=self.initial)
        form.create_tools_field(slug)
        return render(request,  self.template_name, {'form': form})

丹尼尔,如果你成功地实现了你的目标,你可能应该写一个问题的答案。是的,谢谢你的提醒!几分钟后就可以了。