首頁  >  文章  >  後端開發  >  Django計畫實戰之用戶頭像上傳與訪問

Django計畫實戰之用戶頭像上傳與訪問

不言
不言原創
2018-04-21 14:49:062241瀏覽

這篇文章主要介紹了Django專案實戰之用戶頭像上傳與訪問的範例,現在分享給大家,也給大家做個參考。一起來看看吧

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 %}
  <p>用户名:<input type="text" name="username"></p>
  <p>头像<input type="file" name="avatar"></p>
  <input type="submit" value="提交">
</form>
</body>
</html>

urls.py


from django.conf.urls import url
from app01 import views
urlpatterns = [
  url(r&#39;^upload&#39;,views.upload)
]

#views.py


##
from django.shortcuts import render,HttpResponse 
def upload(request):
  if request.method == &#39;POST&#39;:
    name = request.POST.get(&#39;username&#39;)
    avatar = request.FILES.get(&#39;avatar&#39;)
    with open(avatar.name,&#39;wb&#39;) as f:
      for line in avatar:
        f.write(line)
    return HttpResponse(&#39;ok&#39;)
  return render(request,&#39;upload.html&#39;)

總結


這樣,我們就做好了一個基本的檔案上傳小範例,這裡需要注意的有幾點:

 1.form表單裡需要加上csrf_token驗證

 2.檔案的input框的type的值為file
 3.在檢視函數中取得檔案要用request.FILES.get()方法
 4.透過obj.name可以取得檔案的名稱


2 將檔案上傳到資料庫


#models.py


##

from django.db import models
 class User(models.Model):
  username = models.CharField(max_length=16)
  avatar = models.FileField(upload_to=&#39;avatar&#39;)

views.py


def upload(request):
  if request.method == &#39;POST&#39;:
    name = request.POST.get(&#39;username&#39;)
    avatar = request.FILES.get(&#39;avatar&#39;)
    models.User.objects.create(username=name,avatar=avatar)
    return HttpResponse(&#39;ok&#39;) 
  return render(request,&#39;upload.html&#39;)

#總結

##上面已經實現了將檔案上傳到資料庫的功能,需要注意的有幾點: 1.所謂的上傳到資料庫,不是講圖片本身或二進位碼放在資料庫,實際上也是將檔案上傳到伺服器本地,資料庫只是存了一個檔案的路徑,這樣使用者要呼叫檔案的時候就可以透過路徑去伺服器指定的位置找了
 2.建立ORM的時候,avatar欄位要有一個upload_to=''的屬性,指定上傳後的檔案放在哪裡

 3.往資料庫新增的時候,檔案欄位屬性賦值跟普通欄位在形式上是一樣的,如:models.User.objects.create(username=name,avatar=avatar)

 4.如果有兩個使用者上傳的檔案名稱重複,系統會自動將檔案改名,效果如下:




附加

功能我們是實作了,看起來我們在呼叫檔案的時候,只需要透過資料庫檔案路徑已經儲存的檔案本身就可以存取圖片,讓它出現在網頁上,其實並不是這樣,

我們需要配置一些東西,django才可以找的到,不然的話就會過不了urls驗證,而我們之所以可以直接訪問static裡的靜態文件,是因為django已經幫我們配置好了。



設定步驟如下:

#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&#39;^media/(?P<path>.*)$&#39;, serve, {&#39;document_root&#39;: 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 %}
  <p>用户名:<input id="name-input" type="text"></p>

  <p>头像<input id="avatar-input" type="file"></p>
  <input id="submit-btn" type="button" value="提交">
</form>
<script src="/static/js/jquery-3.2.1.min.js"></script>
<script>
  $(&#39;#submit-btn&#39;).on(&#39;click&#39;,function () {
    formdata = new FormData();
    formdata.append(&#39;username&#39;,$(&#39;#name-input&#39;).val());
    formdata.append("avatar",$("#avatar")[0].files[0]);
    formdata.append("csrfmiddlewaretoken",$("[name=&#39;csrfmiddlewaretoken&#39;]").val()); 
 $.ajax({
 processData:false,contentType:false,url:&#39;/upload&#39;, type:&#39;post&#39;, data:formdata,success:function (arg)
 { 
if (arg.state == 1){ alert(&#39;成功!&#39;) }
else { alert(&#39;失败!&#39;) } } }) });
 </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 == &#39;POST&#39;:
    name = request.POST.get(&#39;username&#39;)
    avatar = request.FILES.get(&#39;avatar&#39;)
    try:
      models.User.objects.create(username=name,avatar=avatar)
      data = {&#39;state&#39;:1}
    except:
      data = {&#39;state&#39;:0}
    return JsonResponse(data)
  return render(request,&#39;upload.html&#39;)


##總結

1.Ajax上傳的時候,按鈕的tpye一定不要用submit

2.Ajax上傳的時候data參數的值不再是一個普通'字典'類型的值,而是一個FormData物件


建立物件formdata = new FormData(); 


    往裡面新增值formdata.append('username',$( '#name-input').val());
  1. 3.Ajax在做post提交的時候要加上csrf驗證
  2. formdata.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val());

    4.最後,Ajax上傳檔案的時候要有兩個參數設定
  1. processData:false

    #contentType:false
  1. # 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">
    <p>头像<input id="avatar-input" hidden type="file"></p>

  </label>
  <input id="submit-btn" type="button" value="提交">
</form>
<script src="/static/js/jquery-3.2.1.min.js"></script>
<script>
  // 上传文件按钮(label里的图片)点击事件
  $(&#39;#avatar-input&#39;).on(&#39;change&#39;,function () {
    // 获取用户最后一次选择的图片
    var choose_file=$(this)[0].files[0];
    // 创建一个新的FileReader对象,用来读取文件信息
    var reader=new FileReader();
    // 读取用户上传的图片的路径
    reader.readAsDataURL(choose_file);
    // 读取完毕之后,将图片的src属性修改成用户上传的图片的本地路径
    reader.onload=function () {
       $("#avatar-img").attr("src",reader.result)
    }
  });
</script>

#5 大總結

對於檔案上傳,不管是直接form提交也好,Ajax提交也好,根本問題是要告訴瀏覽器你要上傳的是一個檔案而不是普通的字串

而怎麼樣告訴瀏覽器呢,就是透過請求體重的ContentType參數,我們上傳普通的字串的時候不用指定,因為它有預設值,

而如果要傳文件的話,就要另外指定了。總結以下幾點
 1.form表單上傳的話是透過enctype="multipart/form-data" 來指定ContentType

 2.ajax上傳的話是透過  processData:false 和contentType:false來指定ContentType

3.form上傳的時候,檔案資料是透過3525558f8f338d4ea90ebf22e5cde2bc標籤來''包裹''數據,
 4.ajax上傳的時候,是透過一個FormData 實例物件來新增數據,傳遞的時候傳遞這個物件就行了

 5.資料傳遞過去之後,是封裝在request.FILES裡,而不是request.POST裡



#相關推薦:

#

Django如何載入css和js檔案以及靜態圖片

django控制項及傳參使用詳解

#

以上是Django計畫實戰之用戶頭像上傳與訪問的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn