ChoiceField在重写BaseForm类的init方法后消失

问题描述 投票:0回答:1

我的应用程序是从上传的CSV文件中读取的标头值,并将这些标头传递到扩展Form的另一个类中。目标是最终将此传递的标头列表填充到ChoiceField中。为了得到参数,我覆盖了__init__

以某种方式覆盖__init__,我的选择字段消失了,没有任何异常出现。当我直接使用ChoiceFields而不覆盖__init__方法时,将显示choiceField。我尝试修改并采用不同的重写方法来获取参数,但由于在每种情况下ChoiceField都丢失了,因此无法成功。我正在使用python version 3.7.1Django version 1.9.8。任何意见,将不胜感激。

1.views.py:

def simple_upload(request):

    if request.method == 'POST' and request.FILES['myfile']:
        myfile = request.FILES['myfile']
        fs = FileSystemStorage()
        fs.save(myfile.name, myfile)
        for row in myfile:
            headerlist = row.decode('utf-8').split(",")
            break
        expense_form = ExpenseForm(headerlist)
        return visualize_view(request, expense_form)

    return render(request, 'core/simple_upload.html')


def visualize_view(request, expense_form):
    return render(request,'core/visualize_view.html',{'expense_form':expense_form})

2.forms.py:

from django import forms


class ExpenseForm(forms.Form):

 def __init__(self, headerlist, *args, **kwargs):
    super(ExpenseForm,self).__init__(*args, **kwargs)
    CHOICES = []
    for i in range(len(headerlist)):
        c = (i, headerlist[i])
        CHOICES.append(c)

    columns = forms.ChoiceField(choices=CHOICES)

3.visualize.py:

{% extends 'base.html' %}

{% block content %}

{{ expense_form.as_p }}

{% endblock %}

编辑:

4.urls.py

from django.conf.urls import url
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from uploads.core import views

urlpatterns = [
    url(r'^$', views.loginForm, name='loginForm'),
    url(r'^uploads/', views.simple_upload, name='simple_upload'),
    url(r'^admin/', admin.site.urls),
]


urlpatterns += static(settings.MEDIA_URL, document_root=settings.AKASH_ROOT)
python django
1个回答
1
投票

该字段不会“消失”。从来没有首先在表单中定义过它。

在此代码中,columns__init__方法内部的局部变量。该方法返回后,局部变量将被销毁。

要动态创建字段,您需要将其分配给实例的fields字典。因此:

self.fields['columns'] = forms.ChoiceField(choices=CHOICES)

另外请注意,您的代码不是Python风格,可以大大简化:

CHOICES = [(i, header) for i, header in enumerate(headerlist)]

这时您可以将其直接放在类主体的字段定义中,而无需完全定义__init__

© www.soinside.com 2019 - 2024. All rights reserved.