我正在开发一个DIY应用程序(Django 1.5),我遇到了障碍。涉及的主要模型是Guide
,Tool
,Item
,Step
。指南可以包含许多工具和项目,工具或项目可以属于许多指南。步骤也是如此 - 它可以有许多工具和项目,工具或项目可以属于许多步骤。指南有很多步骤,步骤属于指南。
指南多对多项目
指南多对多工具
指南一对多步骤
步骤多对多项
步骤多对多工具
路障......
在指南级别,我希望工具和项目选项是无限的。但是在步骤级别,我希望工具和项目选项仅限于分配给它所属的指南的选项。基本上,在创建/编辑步骤时,我想列出通过指南提供的所有工具和项目的复选框。用户选择当前步骤所需的那些。每个步骤都有不同的工具和项目组合(因此需要复选框)。
我发现了Step的ModelForm类的ModelMultipleChoiceField
。在那里,我可以指定一个查询集。 但是,如何获取对Guide模型实例的访问权以检索其工具和项目,以便我可以正确构建选择? 我想提供类似于你会在视图中做什么...
Guide.objects.get(pk=n).tools.all()
Guide.objects.get(pk=n).items.all()
如何通过ModelMultipleChoiceField
实现这一目标?我希望我能够清楚地解释这一点。
提前感谢您的帮助。
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
进一步阅读后,看起来我必须覆盖__init__
的{{1}}方法,在那里我获得对ModelMultipleChoiceField
的引用,允许我创建我的查询,self.instance
和self.instance.guide.tools.all()
。然后通过self.instance.guide.items.all()
创建字段。
我现在在工作,所以直到今晚晚些时候才能尝试这个。我会报告我的调查结果。
答案 0 :(得分:0)
我最终做的是以下内容。我在ModelForm类中定义了一个用于创建ModelMultipleChoiceField
的方法。原因是在请求创建步骤页面时,没有与步骤关联的指南,直到您保存(POST ...假设验证成功)。但我确实可以访问指南中将创建Step的slug字段。我从URL获得。 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'})
)
...
<强> views.py 强>
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})