Django - Checkboxes&很多在TemplateView中的很多关系

时间:2017-07-26 14:31:11

标签: django django-models django-forms

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

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)

我想要的是拥有一个庞大的服务列表,其名称后面有复选框,因此所有者可以快速选择他想要连接到他的模型的服务。这曾经是通过管理界面完成的,但是由于受欢迎的需求,这个功能被转移到前面的#39;。

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

我正在尝试一种更加自定义的解决方案,但是已经碰壁了,我想知道你是否可以帮助我。我创建了一个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>

我正在使用以下ModelForm:

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

        widgets = {
            'linked_tenants' : CheckboxSelectMultiple()
        }

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

类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&#39;过滤服务。视图也可以按预期工作。

我所遇到的问题围绕着“拯救”这一事实。崩溃程序,抛出以下错误。

'super' object has no attribute 'post'

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

  1. 该视图可能未正确配置以处理&#39; post&#39;数据
  2. 以后是否将数据处理到数据库是有疑问的。
  3. 虽然是&#39; sollution&#39;目前存在缺陷,我们正朝着正确的方向前进吗?我们是否正确地解决了我们的问题?

    此致

2 个答案:

答案 0 :(得分:1)

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

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

  • 将用户检查过的所有ID都收集到request.POST
  • 的列表中
  • 更新相应对象的M2M字段以包含这些新ID。
  • 保存前面提到的对象。

[编辑]

  

我遇到的一件事就是收集ID&#39;来自request.POST。你能给我一个如何做到这一点的例子吗?

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

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

但是为了教你如何钓鱼而不是给你一条鱼,你应该试着简单地说:

print request.POST.items()

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

答案 1 :(得分:1)

您的第一点是正确的:TemplateView没有定义“post”方法,这就是您在调用super()。form_valid时收到错误消息的原因。您必须自己定义它或使用具有可以覆盖的post方法的CBV(例如UpdateView)

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

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

我有一个类似的问题需要解决(从前端的多对多字段中选择值),我最终“手动”完成了这项工作,因为我无法使用CBV。 “副手”=&gt;解析表单中的值,更新数据库,返回HttpResponse

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

希望这有帮助! 亚历