我遇到了一个问题:如果我想通过添加引导程序代码来动态地应用此行(请参阅bootstrap),则我将不知道用户会预先上传多少个文件。(尽管我定义了最大允许上传的文件数:10) 我正在使用Django 2.1.5。 我试图在form.py中编写类似UploadFileForm的内容,但是那样,我需要在类中准确地编写 10 form.Charfield ,这是我不愿看到的。
<form action="" method="post" enctype="multipart/form-data" id="bookform">
{% csrf_token %}
<table id="createBookTable" class=" table order-list">
<thead>
<tr>
<td>book title(in original lang.)</td>
<td>author(in original lang.)</td>
<td>book title(in Eng.)</td>
<td>author(in Eng.)</td>
<td>book image</td>
</tr>
</thead>
<tbody>
<tr style="display:none">
<td colspan="5" style="text-align: left;" >
<input type="text" id="counter" name="counter" value=""/>
</td>
</tr>
<tr class="bookTr" id="bookTr-0">
<td class="col-sm-3">
<input type="text" name="orginBookname0" class="form-control" />
</td>
<td class="col-sm-3">
<input type="mail" name="originAuthor0" class="form-control"/>
</td>
<td class="col-sm-3">
<input type="text" name="engBookname0" class="form-control"/>
</td>
<td class="col-sm-3">
<input type="text" name="engAuthor0" class="form-control"/>
</td>
<td>
<input type="file" name="bookimg0">
</td>
<td class="col-sm-1"><a class="deleteRow"></a>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" style="text-align: left;">
<input type="button" class="btn btn-lg btn-block " id="addrow" value="Add Row" />
</td>
</tr>
<tr>
<td colspan="5" style="text-align: left;">
<input type="submit" name="button" id="bookSubmitBtn" class="btn btn-lg btn-block btn-beautiful" value="Submit">
</td>
</tr>
</tfoot>
</table>
</form>
这些是上述引导程序演示示例的修改版本:
var counter = 0;
$("#counter").prop('value',counter);
$("#addrow").on("click", function () {
if(counter<=9){
counter++;
var newRow = $('<tr class="bookTr" id="bookTr-'+counter+'">');
var cols = "";
cols += '<td><input type="text" class="form-control" name="orginBookname' + counter + '"/></td>';
cols += '<td><input type="text" class="form-control" name="originAuthor' + counter + '"/></td>';
cols += '<td><input type="text" class="form-control" name="engBookname' + counter + '"/></td>';
cols += '<td><input type="text" class="form-control" name="engAuthor' + counter + '"/></td>';
cols += '<td><input type="file" name="bookimg' + counter + '"/></td>';
cols += '<td><input type="button" class="ibtnDel btn btn-md btn-danger " value="Delete"></td>';
newRow.append(cols);
$("table.order-list").append(newRow);
$("#counter").prop('value',counter);
}
else{
alert("You can only add 10 books per time.");
}
});
预期结果是将用户选择的所有文件上载到media \ photos文件夹。同样,我们无法预先知道它们将上传多少文件。 我想在Django框架下的前端使用ajax调用。
答案 0 :(得分:0)
我认为您正在寻找表单集。您可以使用django formset动态呈现和上传任意数量的表单字段。在这里https://github.com/elo80ka/django-dynamic-formset
中查看答案 1 :(得分:0)
我找到了一种避免使用form.py而是使用ajax调用的方法。 在settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
在urls.py
中urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
在models.py
中class book(models.Model):
titleOrigin = models.CharField(max_length=200,null = False)
authorOrigin = models.CharField(max_length=100,null = True)
titleEnglish = models.CharField(max_length=200,null = True)
authorEnglish = models.CharField(max_length=100,null = True)
bookImgFname = models.CharField(max_length=300,null=True)
在createbook.js中(使用 FormData()函数!!!):
function upload(event) {
event.preventDefault();
var formdata = new FormData($('#bookform').get(0));
$.ajax({
url: '/createbook/',
type: 'post',
data: formdata,
cache: false,
processData: false,
contentType: false,
success: function(data) {
alert('success');
}
});
return false;
}
$(function() {
$('#bookform').submit(upload);
});
在views.py中,使用 FileSystemStorage 和 request.FILES ['bookimg'+ str(i)] (感谢this tutorial)
def createbook(request):
if request.method == 'POST' and request.is_ajax():
for i in range(int(request.POST.get('counter'))+1): **#the nondisplayed counter is a trick**
curOrginBookname = request.POST.get('orginBookname'+str(i))
curOriginAuthor = request.POST.get('originAuthor'+str(i))
curEngBookname = request.POST.get('engBookname'+str(i))
curEngAuthor = request.POST.get('engAuthor'+str(i))
curBookimg = request.FILES['bookimg'+str(i)]
fss = FileSystemStorage()
concatenatedFname = curOrginBookname+"_"+curBookimg.name
fss.save("photos\\"+concatenatedFname, curBookimg)
bookToBeSaved = book(titleOrigin=curOrginBookname,authorOrigin=curOriginAuthor,
titleEnglish=curEngBookname,authorEnglish=curEngAuthor,bookImgFname=concatenatedFname)
bookToBeSaved.save()
return HttpResponse('')
else:
return render(request, "createbook.html", locals())
记住要导入:
from django.core.files.storage import FileSystemStorage