django本地文件展示(Django上传文件)
文件上传是网站开发中非常常见的功能这里详细讲述如何在 Django 中实现文件的上传功能,我来为大家讲解一下关于django本地文件展示?跟着小编一起来看一看吧!
django本地文件展示
文件上传是网站开发中非常常见的功能。这里详细讲述如何在 Django 中实现文件的上传功能。
前端HTML代码实现:- 在前端中,我们需要填入一个 form 标签,然后在这个 form 标签中指定 enctype="multipart/form-data",不然就不能上传文件。
- 在 form 标签中添加一个 input 标签,然后指定 input 标签的 name,以及 type="file"。
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="myfile">
</form>
后端的主要工作是接收文件,然后存储文件。接收文件的方式跟接收 POST 的方式是一样的,只不过是通过 FILES 来实现。示例代码如下:
def save_file(file):
with open('somefile.txt','wb') as fp:
for chunk in file.chunks():
fp.write(chunk)
def index(request):
if request.method == 'GET':
form = MyForm()
return render(request,'index.html',{'form':form})
else:
myfile = request.FILES.get('myfile')
save_file(myfile)
return HttpResponse('success')
以上代码通过 request.FILES 接收到文件后,再写入到指定的地方。这样就可以完成一个文件的上传功能了。
使用模型来处理上传的文件在定义模型的时候,我们可以给存储文件的字段指定为 FileField,这个 Field 可以传递一个 upload_to参数,用来指定上传上来的文件保存到哪里。比如我们让他保存到项目的 files 文件夹下,那么示例代码如下:
# models.py
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
thumbnail = models.FileField(upload_to="files")
# views.py
def index(request):
if request.method == 'GET':
return render(request,'index.html')
else:
title = request.POST.get('title')
content = request.POST.get('content')
thumbnail = request.FILES.get('thumbnail')
article = Article(title=title, content=content, thumbnail=thumbnail)
article.save()
return HttpResponse('success')
调用完 article.save() 方法,就会把文件保存到files下面,并且会将这个文件的路径存储到数据库中。
指定MEDIA_ROOT和MEDIA_URL:以上我们是使用了 upload_to 来指定上传的文件目录。我们也可以指定 MEDIA_ROOT,就不需要在FielField 中指定 upload_to,他会自动的将文件上传到 MEDIA_ROOT 的目录下。
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
MEDIA_URL = '/media/'
然后我们可以在urls.py中添加MEDIA_ROOT目录下的访问路径。示例代码如下:
from django.urls import path
from front import views
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('', views.index),
] static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
如果我们同时指定MEDIA_ROOT和upload_to,那么会将文件上传到MEDIA_ROOT下的upload_to文件夹中。示例代码如下:
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
thumbnail = models.FileField(upload_to="%Y/%m/%d/")
如果想要限制上传的文件的拓展名,那么我们就需要用到表单来进行限制。我们可以使用普通的 Form表单,也可以使用 ModelForm,直接从模型中读取字段。示例代码如下:
# models.py
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
thumbnial = models.FileField(upload_to='%Y/%m/%d/',validators=[validators.FileExtensionValidator(['txt','pdf'])])
# forms.py
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = "__all__"
上传图片跟上传普通文件是一样的。只不过是上传图片的时候 Django 会判断上传的文件是否是图片的格式(除了判断后缀名,还会判断是否是可用的图片)。如果不是,那么就会验证失败。我们首先先来定义一个包含ImageField的模型。示例代码如下:
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
thumbnail = models.ImageField(upload_to="%Y/%m/%d/")
因为要验证是否是合格的图片,因此我们还需要用一个表单来进行验证。表单我们直接就使用 ModelForm就可以了。示例代码如下:
class MyForm(forms.ModelForm):
class Meta:
model = Article
fields = "__all__"
注意:使用ImageField,必须要先安装Pillow库:pip install pillow
使用Ajax上传文件利用Ajax上传文件的好处是上传文件后无需刷新页面或调整即可立即显示文件上传信息。
前端
<div>
<input type="file" name="file" id="file_upload">
<input type="button" value="上传" onclick="FileUpload()">
</div>
<script src="/static/js/jquery-3.2.1.min.js"></script>
<script>
function FileUpload() {
var form_data = new FormData();
var file_info =$( '#file_upload')[0].files[0];
form_data.append('file',file_info);
if(file_info==undefined) { #暂且不许要判断是否有附件
alert('你没有选择任何文件');
return false
}
$.ajax({
url:'/upload_ajax/',
type:'POST',
data: form_data,
processData: false, // tell jquery not to process the data
contentType: false, // tell jquery not to set contentType
success: function(callback) {
console.log('ok')
}
});
}
</script>
后端
def upload_ajax(request):
if request.method == 'POST':
file_obj = request.FILES.get('file')
import os
f = open(os.path.join(BASE_DIR, 'static', 'pic', file_obj.name), 'wb')
print(file_obj,type(file_obj))
for chunk in file_obj.chunks():
f.write(chunk)
f.close()
print('11111')
return HttpResponse('OK')
现在我们在做 web 开发的时候,基本上都使用前后端分离框架,vue 作为后起之秀,应用范围也是非常广的。前端示例代码如下:
<template>
<div>
添加商品<input v-model="name"><br>
价格<input v-model="price"><br>
商品照片<input type="file" id="ssss"><br>
<button @click="add">添加</button>
</div>
</template>
<script>
export default {
name: "addcate",
data:function () {
return{
name:'',
price:'',
}
},
methods: {
add:function () {
var data = new FormData();
data.append('name',this.name);
data.append('price',this.price);
var image =document.getElementById('ssss').files[0];
data.append('file',image);
this.axios({
url:'/api/sadmin/addcate/',
data:data,
method:'post'
}).then((res)=>{
if (res.data.code==200){
this.$router.push({'path':'show'})
}
alert(res.data.message)
}).catch((err)=>{
console.log(err)
})
}
}
}
</script>
<style scoped>
</style>
后端示例代码如下:
class Addcate(APIView):
def post(self,request):
res={}
name = request.data.get('name')
price = request.data.get('price')
image = request.data.get('file')
if not all([name,price,image]):
res['code']=10020
res['message']='输入不能为空'
else:
image_name = image.name
image_path = os.path.join(settings.UPLOAD_FILE,image_name)
f = open(image_path,'wb')
for i in image.chunks():
f.write(i)
f.close()
goods = Goods.objects.filter(name=name).first()
if goods:
res['code']=10023
res['message']='商品已存在'
else:
goods = Goods(name=name,price=price,image='/upload/' image_name)
goods.save()
res['code']=200
res['message']='添加成功'
return JsonResponse(res)
return JsonResponse(res)
# 在settings中做如下配置
STATICFLIES_DIRS=[os.path.join(BASE_DIR,'static')]#照片存放在static文件下
UPLOAD_FILE=os.path.join(BASE_DIR,'upload')#照片存放在根目录upload文件下
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com