django - 如何将对象传递到表单并在 Django 中提交它们

标签 django object django-forms

我有一个允许从 CSV 文件导入的应用程序。 CSV 文件中包含库列表。我需要首先将它们解析为库实例列表,将它们显示在另一个页面上,用户单击“确认”后,这些库被保存。

这是我的表格:

class LibCsvForm(forms.Form):
    lib_csv  = forms.FileField(label='CSV file')

class LibListForm(forms.Form):
    def __init__(self, *args, **kwargs):
        new_libs = kwargs.pop('new_libs')
        super(LibListForm, self).__init__(*args, **kwargs)
        self.fields['new_libs'] = new_libs

我的观点:

def import_lib_csv(request):
    if request.method == 'POST':
        form = LibCsvForm(request.POST, request.FILES)
        if form.is_valid():
            raw = request.FILES['lib_csv'].read()
            new_libs = []
            # Process string 'raw' and add instances of Library to new_libs
            context = RequestContext(request, {'form': LibListForm(new_libs=new_libs)})
            context.update(csrf(request))
            return render_to_response('master/library.csv.confirm.html', context)
    else:
        form = LibCsvForm()
    variables = RequestContext(request, { 'form': form })
    return render_to_response('master/library.csv.html', variables)

LibCsvForm仅供用户上传文件。方法“import_lib_csv”是读取文件,创建实例,并将它们传递给另一个表单LibListForm,该表单仅包含“new_libs”。用户单击“确认”后,我想获取此列表并保存对象。

问题在于,在模板中:

{{ form.new_libs }}
{% for lib in new_libs %}
     {{ lib.id }}
{% endfor %}

它没有显示任何内容。我认为我没有正确地将“new_libs”传递到表单中。有人可以帮忙吗?谢谢。


编辑:

谢谢,罗汉。我按照你提到的修改了它。现在库列表可以显示在模板中。 “new_libs”是库实例的列表。

但是当我点击“确认”时,它报告错误。这是我的保存方法:

def save_lib_list(request):
    if request.POST:
        form = LibListForm(request.POST)
        print form.cleaned_data['new_libs']
    variables = RequestContext(request, {
        'lib_list': Library.objects.all()
    })
    return render_to_response('master/library.list.html', variables) 

Django 说

"Exception Type:    KeyError
Exception Value:    'new_libs' "

我的模板是:

<form method="post" action="/library/savelist/" class="well">
    {% csrf_token %}
    <legend>Libraries to import</legend>
    {% for lib in new_libs %}
        {{ lib.id }}
    {% endfor %}
</form>

我想我在这里错过了一些东西,但不知道如何解决......


已解决:

首先将上传的 CSV 文件的内容保存在服务器上。将此文件的路径设置为 LibListForm 中的隐藏字段:

tmp_lib_file = forms.CharField(widget=forms.HiddenInput(), initial='tmp.lib')

然后,当用户单击“确认”时,再次解析文件并获取 Library 实例,保存它们。

最佳答案

如果您想在模板中使用new_libs,您应该在模板上下文中添加它。

context = RequestContext(request, {'form': LibListForm(new_libs=new_libs), 'new_libs': new_libs})

此外,您传递给 LibListFormnew_libs 类型是什么?如果它不是正确的字段类型,则无法正确显示/处理。

问题编辑后更新:

  • 该错误表明 form.cleaned_data 中没有 new_fields 键。该表单应该有一个具有该名称的字段。 new_field 似乎不是表单字段。
  • 您的模板也没有表单字段吗?

关于django - 如何将对象传递到表单并在 Django 中提交它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12229832/

相关文章:

python - 为什么这个 Django 匹配在 urls.py 中不起作用?

django - 如何从django-mptt创建一个json树?

Python 不能正确解释 UTF8

javascript - 如何将数组传递给 map ?句法

没有必填字段的 Django 表单

django - 从 django 获取一个可为 null 的日期时间并将其转换为 golang

javascript - 在一个对象中找到一个为真的键并且匹配数组中的条目

java - 如果我想根据不同的属性以不同的方式搜索一个对象,应该使用什么数据结构?

django - 如何在 JSONField 上使用 django-filter

python - Django - 成功登录后将用户重定向到 "next"参数