Django - TemplateView 中的复选框和 ManytoMany 关系



>我有一个应用程序,用户可以在其中注册他们的公司,然后从列表中选择一些设置。公司和服务都是不同的模式。

class Company(models.Model):
name = models.CharField(max_length=100)
(...)
class Service(models.Model):
name = models.CharField(max_length=100)
linked_companies = ManyToManyField(Company, blank=True)

我想要的是有一个很大的服务列表,名称后面有复选框,这样所有者就可以快速选择要连接到他的模型的服务。这曾经是通过管理界面完成的,但由于大众需求,此功能被移至"前端"。

问题是我不知道如何将其融入我们迄今为止一直在使用的传统(通用(视图/表单组合中,因为涉及两种不同的模型。

我正在尝试更自定义的解决方案,但遇到了困难,我想知道您是否可以帮助我。我创建了一个 html 页面,应该同时显示服务列表和"保存"按钮。

<form action="." method="POST" class="post-form">{% csrf_token %}
<ul>
{% recursetree services %}
<li>
<label><input type="checkbox" name='service' value={{ node.pk }}><h3>{{ node.name }}</h3></label>
{% if not node.is_leaf_node %}
<ul class="children">
{{ children }}
</ul>
{% endif %}
</li>
{% endrecursetree %}
</ul>
<button type="submit" class="save btn btn-default">Add Selected
</button>
</form>

我正在使用以下模型表单:

class FacetForm(forms.ModelForm):
class Meta:
model = Services
fields = ['linked_tenants', 'name']
widgets = {
'linked_tenants' : CheckboxSelectMultiple()
}

此 HTML 页面似乎按预期工作,显示一长串服务,名称后带有复选框。 但是,我在创建函数视图时遇到问题。与同事一起创建了以下视图

class FacetList(TenantRootedMixin, TemplateView(:

def get_context_data(self, **kwargs):
d = super(ServiceList, self).get_context_data(**kwargs)
d['services'] = Services.objects.all()
d['current_company'] = self.context.company.id
return d
def form_valid(self, *args, **kwargs):
return super(ServiceList, self).form_valid(*args, **kwargs)

此视图的工作原理是它显示所有相关信息(带有复选框(。如果我更改查询以按"公司 ID"过滤服务。视图也可以根据需要工作。

我的问题围绕着按"保存"的事实。 使程序崩溃,引发以下错误。

'super' object has no attribute 'post'

我们的程序主要通过基于类的通用视图和模型窗体工作,因此我们在创建自己的自定义解决方案方面的经验相对有限。根据我自己的估计,问题似乎是双重的:

  1. 视图可能未正确配置以处理"发布"数据
  2. 之后是否会将数据处理到数据库中是值得怀疑的。

虽然"解决方案"目前存在缺陷,但我们是否朝着正确的方向前进?我们是否在解决问题的正确方法上?

问候

我相信你走在正确的轨道上。我的建议是不要害怕放弃通用视图并转向更自定义的解决方案(即使您对此缺乏经验(。

我想到的第一个例程如下:

  • 将用户检查的所有 ID 收集到一个列表中request.POST
  • 更新相应对象的 M2M 字段以包含这些新 id。
  • 保存上述对象。

[编辑]

我遇到麻烦的一件事是从 request.POST 收集 ID。 你能给我一个如何做到这一点的例子吗?

当然,从您的 HTML 文件中我看到您正在使用name=service创建输入。这让我相信你可以做这样的事情:

ids = request.POST.get('service')

但要教你如何钓鱼而不是给你一条鱼,你应该尝试简单地:

print request.POST.items()

这会将从表单发布的所有内容返回并打印到控制台到视图功能。使用它来了解您是否要从模板到服务器获取 id 列表。如果没有,您可能需要重新评估如何在模板中构建表单。

你的第一点是正确的:TemplateView 没有定义"post"方法,这就是为什么当你调用 super((.form_valid 时收到错误消息的原因。您必须自己定义它,或者使用具有可以覆盖的发布方法的 CBV(例如 UpdateView(

我也相信你的第二点是正确的。

您需要使用 UpdateView 才能使用内置功能(或 CreateView(。

我有一个类似的问题需要解决(从前端的多对多字段中选择值(,我最终"手动"完成,因为我无法让它与 CBV 一起使用。"手动" => 解析表单中的值,更新数据库,返回 HttpResponse

您可能想查看ModelFormSets: https://docs.djangoproject.com/en/1.11/topics/forms/modelforms/#model-formsets

希望这有帮助! 亚历克斯

最新更新