如何动态地将参数传递给Django中的表单?

时间:2019-10-08 06:35:33

标签: django python-3.x django-forms

我有一个“ BasicSearch”表格,其中有两个字段。一个是名为“ search_by”的选择字段,而另一个是名为“ search_for”的文本字段。我有针对客户,供应商,物料,项目和其他几个模型。 我想做的是通过在文本字段中提供查询并从选择字段中选择他们要搜索的内容(模型的列标题),使用户能够在各自页面上的各种模型上执行搜索。

我已经在stackoverflow上尝试了几种解决方案,但是没有一种对我有用。当我手动创建列标题的字典并将其传递到选择字段时,它可以正常工作。

当前搜索表单类如下所示(哪个不起作用)

class BasicSearch(forms.Form):
    def __init__(self,arg):
        super(BasicSearch, self).__init__(arg)
        caller = arg
        if caller == 'customer':
            cu = Customers()
        field_dct = get_col_heads(cu)
        self.fields['search_by'] = forms.ChoiceField(choices=field_dct,widget=forms.Select(attrs={'class':'form-control'}))
        self.fields['search_for'] = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control'}))

get_col_heads函数:

def get_col_heads(cu):
    all_fields = cu._meta.fields
    all_field_list = []
    for fields in all_fields:
        column_head = (str(fields)).split(".")
        all_field_list.append(column_head[-1])
        field_list = all_field_list[1:-2]
        field_dct = tuple(zip(field_list,field_list))
    return field_dct

客户在view.py中查看类

class IndexView(TemplateView):
    template_name = 'crudbasic/index.html'
    def get_context_data(self,**kwargs):
        context = super().get_context_data(**kwargs)
        context ['page_title'] = ''
        return context

class CustomerView(ListView):
    template_name = 'crudbasic/customers.html'
    model = Customers
    context_object_name = 'customer_data'

    def get_context_data(self,**kwargs):
        context = super().get_context_data(**kwargs)
        context['search_form'] = BasicSearch('customer')
        return context

    def post(self, request, *args, **kwargs):
        search_form = BasicSearch(request.POST)
        if search_form.is_valid():
            data = request.POST.copy()
            qby = data.get('search_by')
            qstrting = data.get('search_for')
            queryparam = qby+'__'+'contains'
            search_list = Customers.objects.filter(**{queryparam:qstrting})
            customer_data = search_list
        return render(request, self.template_name, {'customer_data': customer_data,'search_form':search_form})

当我在表单字段中放入 init 时,为了采用用于选择相应模型/表的参数,然后从表列标题中生成字典,这一切都麻烦了。当前带有上面的代码,它给我以下错误。

AttributeError at /customers/
'str' object has no attribute 'get'

如果有人知道该怎么做,请提供帮助。

谢谢

1 个答案:

答案 0 :(得分:0)

您的__init__表单类的自定义BasicSearch方法不尊重表单可以具有的所有其他参数。你做不到一种更合适的方法是使用自定义kwarg参数,如下所示:

class BasicSearch(forms.Form):
    def __init__(self, *args, **kwargs):
        caller = kwargs.pop('caller')
        super(BasicSearch, self).__init__(*args, **kwargs)
        # ...


# usage
form = BasicSearch(caller='customer')

# usage with POST
form = BasicSearch(request.POST,  caller='customer')

PS。在python中,所有东西都是对象,甚至是类,因此您不必传递"string"作为调用者,而只需传递类本身即可:form = BasicSearch(caller=Customers)