如何从表单更新多个字段?

时间:2018-03-03 14:43:55

标签: django python-3.x

我有以下两种模式:

class TaskFile(models.Model):
    file = models.FileField(upload_to='task-files/')

    def __str__(self):
        return self.file.name

class Task(models.Model):
    lesson = models.ManyToManyField(TaskFile, related_name='task_files')

我有一个模型表单来更新已创建的Task对象,但多对多的关系不会显示在表单中。它只显示上传文件的选项,而不显示该对象中的现有文件。

我该如何解决这个问题?

编辑:

这是我的模型表单代码:

class TutorTaskSelectForm(forms.ModelForm):
    lesson = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))

    class Meta:
        model = Task
        fields = ('lesson')

这是我的模板:

<form action="{{request.path}}" method="POST" enctype="multipart/form-data">
 {%csrf_token%}
  <div class="box-body">
     <div class="form-group">
       <label for="inputEmail3" class="col-sm-2 control-label">Number</label>

       <div class="col-sm-10">
         {{form.lesson}}
       </div>
     </div>
   </div>
 </form>

1 个答案:

答案 0 :(得分:0)

首先,我不是内置Django Forms的忠实粉丝。所以我建议你采用不同的方式。没有Django Forms的方法。

脱离这个问题的背景:

  

有很棒的,我的意思是非常棒的前端图书馆   ReactVueAngular。而且他们每个人都越来越受欢迎   一天,甚至每一分钟。当你决定选择其中之一   花哨的图书馆,使用Django形式并没有多大意义。

无论如何,如果你想保留现有的模型结构,我认为你能做的最好的事情就是更新你视图中的逻辑:

def index(request):
    if request.method == 'POST':
        print(request.FILES.getlist)
        files = request.FILES.getlist('lesson')

        # @TODO: check if form is valid or files are proper etc. here

        task = Task() # new task instance here
        task.save()

        for f in files:
            task_file = TaskFile()
            task_file.file = f
            task_file.save() # save uploaded file to the TaskFile

            task.lesson.add(task_file) #  here add that file to the many to many field of Task Model

        return HttpResponse('All files saved!')
    else:
        ctx = {
            'form': TutorTaskSelectForm()
        }
        return render(request, 'index.html', ctx)

我测试了上面的代码。这是工作。但是你必须通过说uploading multiple files澄清你的意思。

您想一次选择多个文件吗?或者您是否希望每个文件都有不同的单独文件对话框?

如果您希望在从浏览器对话框中选择文件时multiple selection,则上述解决方案应该适合您。

但是如果你想通过分别选择多个文件来获得多个文件,那么你的html端需要多个inputs。像这样:

<form action="{{ request.path }}" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    <input type="file" name="lesson" required />
    <input type="file" name="lesson" required />
    <input type="file" name="lesson" required />
    <input type="submit" value="Save"/>
</form>

请注意,在这种情况下,您不需要Django表单。只需创建常规输入文件,然后在视图中处理它们。您可以通过调用request.FILES.getlist('lesson')来覆盖请求中的文件。

但同样,我不会在这种情况下使用django表格。这是不使用django表单的版本:

<form action="{{request.path}}" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    <div class="box-body">
        <div class="form-group">
            <label for="inputEmail3" class="col-sm-2 control-label">Number</label>
            <div class="col-sm-10">
                <input type="file" name="lesson" required multiple />
            </div>
        </div>
    </div>
    <input type="submit" value="Save" />
</form>

将这些行放在你的html中,然后使用上面的代码。这是非常基本和简单的。您可以根据自己的要求进行更新。

相关问题