Django項目實戰(zhàn)之用戶頭像上傳與訪問的示例
1 將文件保存到服務器本地
upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div>用戶名:<input type="text" name="username"></div>
<div>頭像<input type="file" name="avatar"></div>
<input type="submit" value="提交">
</form>
</body>
</html>
urls.py
from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^upload',views.upload) ]
views.py
from django.shortcuts import render,HttpResponse
def upload(request):
if request.method == 'POST':
name = request.POST.get('username')
avatar = request.FILES.get('avatar')
with open(avatar.name,'wb') as f:
for line in avatar:
f.write(line)
return HttpResponse('ok')
return render(request,'upload.html')
總結
這樣,我們就做好了一個基本的文件上傳小示例,這里需要注意的有幾點:
1.form表單里需要加上csrf_token驗證
2.文件的input框的type的值為file
3.在視圖函數(shù)中獲取文件要用request.FILES.get()方法
4.通過obj.name可以獲取文件的名字
2 將文件上傳到數(shù)據(jù)庫
models.py
from django.db import models class User(models.Model): username = models.CharField(max_length=16) avatar = models.FileField(upload_to='avatar')
views.py
def upload(request):
if request.method == 'POST':
name = request.POST.get('username')
avatar = request.FILES.get('avatar')
models.User.objects.create(username=name,avatar=avatar)
return HttpResponse('ok')
return render(request,'upload.html')
總結
上面已經(jīng)實現(xiàn)了將文件上傳到數(shù)據(jù)庫的功能,需要注意的有幾點:
1.所謂的上傳到數(shù)據(jù)庫,不是講圖片本身或者二進制碼放在數(shù)據(jù)庫,實際上也是將文件上傳到服務器本地,數(shù)據(jù)庫只是存了一個文件的路徑,這樣用戶要調用文件的時候就可以通過路徑去服務器指定的位置找了
2.創(chuàng)建ORM的時候,avatar字段要有一個upload_to=''的屬性,指定上傳后的文件放在哪里
3.往數(shù)據(jù)庫添加的時候,文件字段屬性賦值跟普通字段在形式上是一樣的,如:models.User.objects.create(username=name,avatar=avatar)
4.如果有兩個用戶上傳的文件名重復,系統(tǒng)會自動將文件改名,效果如下:

附加
功能我們是實現(xiàn)了,看起來我們在調用文件的時候,只需要通過數(shù)據(jù)庫文件路徑已經(jīng)保存的文件本身就可以訪問圖片,讓它出現(xiàn)在網(wǎng)頁上,其實并不是這樣,
我們需要配置一些東西,django才可以找的到,不然的話就會過不了urls驗證,而我們之所以可以直接訪問static里的靜態(tài)文件,是因為django已經(jīng)幫我們配置好了。

配置步驟如下:
1、在站點的setting.py里配置
MEDIA_ROOT=os.path.join(BASE_DIR,"blog","media") #blog是項目名,media是約定成俗的文件夾名 MEDIA_URL="/media/" # 跟STATIC_URL類似,指定用戶可以通過這個路徑找到文件
2、在urls.py里配置
from django.views.static import serve
from upload import settings #upload是站點名
url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
配置完后,就可以通過http://127.0.0.1:8001/media/milk.png訪問到圖片了
3 用AJAX提交文件
upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<form>
{% csrf_token %}
<div>用戶名:<input id="name-input" type="text"></div>
<div>頭像<input id="avatar-input" type="file"></div>
<input id="submit-btn" type="button" value="提交">
</form>
<script src="/static/js/jquery-3.2.1.min.js"></script>
<script>
$('#submit-btn').on('click',function () {
formdata = new FormData();
formdata.append('username',$('#name-input').val());
formdata.append("avatar",$("#avatar")[0].files[0]);
formdata.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val());
$.ajax({
processData:false,contentType:false,url:'/upload', type:'post', data:formdata,success:function (arg)
{
if (arg.state == 1){ alert('成功!') }
else { alert('失?。?) } } }) });
</script>
</body>
</html>
views.py
from django.shortcuts import render,HttpResponse
from django.http import JsonResponse
from app01 import models
def upload(request):
if request.method == 'POST':
name = request.POST.get('username')
avatar = request.FILES.get('avatar')
try:
models.User.objects.create(username=name,avatar=avatar)
data = {'state':1}
except:
data = {'state':0}
return JsonResponse(data)
return render(request,'upload.html')
總結
1.Ajax上傳的時候,按鈕的tpye一定不要用submit
2.Ajax上傳的時候data參數(shù)的值不再是一個普通‘字典'類型的值,而是一個FormData對像
- 創(chuàng)建對象formdata = new FormData();
- 往里面添加值formdata.append('username',$('#name-input').val());
3.Ajax在做post提交的時候要加上csrf驗證
- formdata.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val());
4.最后,Ajax上傳文件的時候要有兩個參數(shù)設置
- processData:false
- contentType:false
4 上傳圖片文件的時候有預覽功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<form>
<!----用一個label標簽將上傳文件輸入框跟圖片綁定一起,
點擊圖片的時候就相當于點擊了上傳文件的按鈕---->
<label><img id="avatar-img" src="/static/img/default.png" width="80px" height="80px">
<div>頭像<input id="avatar-input" hidden type="file"></div>
</label>
<input id="submit-btn" type="button" value="提交">
</form>
<script src="/static/js/jquery-3.2.1.min.js"></script>
<script>
// 上傳文件按鈕(label里的圖片)點擊事件
$('#avatar-input').on('change',function () {
// 獲取用戶最后一次選擇的圖片
var choose_file=$(this)[0].files[0];
// 創(chuàng)建一個新的FileReader對象,用來讀取文件信息
var reader=new FileReader();
// 讀取用戶上傳的圖片的路徑
reader.readAsDataURL(choose_file);
// 讀取完畢之后,將圖片的src屬性修改成用戶上傳的圖片的本地路徑
reader.onload=function () {
$("#avatar-img").attr("src",reader.result)
}
});
</script>
5 大總結
對于文件上傳,不管是直接form提交也好,Ajax提交也好,根本問題是要告訴瀏覽器你要上傳的是一個文件而不是普通的字符串
而怎么樣告訴瀏覽器呢,就是通過請求體重的ContentType參數(shù),我們上傳普通的字符串的時候不用指定,因為它有默認值,
而如果要傳文件的話,就要另外指定了。總結以下幾點
1.form表單上傳的話是通過 enctype="multipart/form-data" 來指定ContentType
2.ajax上傳的話是通過 processData:false 和 contentType:false來指定ContentType
3.form上傳的時候,文件數(shù)據(jù)是通過<input type="file">標簽來‘'包裹‘'數(shù)據(jù),
4.ajax上傳的時候,是通過一個 FormData 實例對象來添加數(shù)據(jù),傳遞的時候傳遞這個對象就行了
5.數(shù)據(jù)傳遞過去之后,是封裝在request.FILES里,而不是request.POST里
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
python利用os模塊編寫文件復制功能——copy()函數(shù)用法
這篇文章主要介紹了python利用os模塊編寫文件復制功能——copy()函數(shù)用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07
Python+threading模塊對單個接口進行并發(fā)測試
這篇文章主要為大家詳細介紹了Python+threading模塊對單個接口進行并發(fā)測試,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-06-06
Python實現(xiàn)將HTML轉為PDF/圖片/XML/XPS格式
網(wǎng)頁內容是信息傳播的主要形式之一,這篇文章主要和大家介紹了如何使用Python實現(xiàn)將HTML分別轉為PDF/圖片/XML/XPS格式等,需要的可以參考下2024-03-03
使用Python中PDB模塊中的命令來調試Python代碼的教程
這篇文章主要介紹了使用Python中PDB模塊中的命令來調試Python代碼的教程,包括設置斷點來修改代碼等、對于Python團隊項目工作有一定幫助,需要的朋友可以參考下2015-03-03
python numpy函數(shù)中的linspace創(chuàng)建等差數(shù)列詳解
numpy.linspace是用于創(chuàng)建一個一維數(shù)組,并且是等差數(shù)列構成的一維數(shù)組,下面這篇文章主要給大家介紹了關于python numpy函數(shù)中的linspace創(chuàng)建等差數(shù)列的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下。2017-10-10

