我有以下两种模式:
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>
答案 0 :(得分:0)
首先,我不是内置Django Forms
的忠实粉丝。所以我建议你采用不同的方式。没有Django Forms
的方法。
脱离这个问题的背景:
有很棒的,我的意思是非常棒的前端图书馆
React
,Vue
或Angular
。而且他们每个人都越来越受欢迎 一天,甚至每一分钟。当你决定选择其中之一 花哨的图书馆,使用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中,然后使用上面的代码。这是非常基本和简单的。您可以根据自己的要求进行更新。