Python筆記:Django框架中上傳文件、數據分頁、部署(Apache)

上傳圖片

  • 當Django在處理文件上傳的時候,文件數據被保存在request.FILES
  • FILES中的每個鍵爲<input type="file" name="" />中的name
  • 注意:FILES只有在請求的方法爲POST 且提交的<form>帶有enctype="multipart/form-data" 的情況下才會包含數據。
  • 否則,FILES 將爲一個空的類似於字典的對象
  • 備註:本文基於django版本1.11展開, 技術棧會有所升級, 僅供參考!

1 ) 自定義上傳的模板代碼

<html>
<head>
    <title>文件上傳</title>
</head>
<body>
    <form method="post" action="upload/" enctype="multipart/form-data">
        <input type="text" name="title"><br>
        <input type="file" name="pic"/><br>
        <input type="submit" value="上傳">
    </form>
</body>
</html>

2 ) 自定義上傳的視圖代碼

from django.shortcuts import render
from django.http import HttpResponse
from PIL import Image
import time,os

def upload(request):
    '''執行圖片的上傳'''
    myfile = request.FILES.get("mypic",None)
    if not myfile:
        return HttpResponse("沒有上傳文件信息")
    filename = str(time.time())+"."+myfile.name.split('.').pop()
    destination = open("./static/pics/"+filename,"wb+")
    for chunk in myfile.chunks():      # 分塊寫入文件  
        destination.write(chunk)  
    destination.close()

    # 執行圖片縮放
    im = Image.open("./static/pics/"+filename)
    # 縮放到75*75(縮放後的寬高比例不變):
    im.thumbnail((75, 75))
    # 把縮放後的圖像用jpeg格式保存: 
    im.save("./static/pics/s_"+filename,None)

    #執行圖片刪除
    #os.remove("./static/pics/"+filename)

    return HttpResponse("上傳成功!圖片:"+filename)

3 ) 使用模型處理上傳文件

  • 將屬性定義成models.ImageField類型 pic=models.ImageField(upload_to='cars/')
  • 注意:如果屬性類型爲ImageField獲使用圖片處理,那麼就需要安裝包Pillow $ pip3 install Pillow
  • 圖片存儲路徑
    • 在項目根目錄下創建media文件夾
    • 圖片上傳後,會被保存到“/static/media/cars/圖片文件”
    • 打開settings.py文件,增加media_root項
      MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")
      
  • 使用django後臺管理,遇到ImageField類型的屬性會出現一個file框,完成文件上傳

分頁操作

  • Django提供了一些類實現管理數據分頁,這些類位於django/core/paginator.py中

Paginator對象

  • Paginator(列表,int):返回分頁對象,參數爲列表數據,每面數據的條數
  • 屬性
    • count:對象總數
    • num_pages:頁面總數
    • page_range:頁碼列表,從1開始,例如[1, 2, 3, 4]
  • 方法
    • page(num):下標以1開始,如果提供的頁碼不存在,拋出InvalidPage異常
  • 異常exception
    • InvalidPage:當向page()傳入一個無效的頁碼時拋出
    • PageNotAnInteger:當向page()傳入一個不是整數的值時拋出
    • EmptyPage:當向page()提供一個有效值,但是那個頁面上沒有任何對象時拋出

Page對象

  • 創建對象

    • Paginator對象的page()方法返回Page對象,不需要手動構造
  • 屬性

    • object_list:當前頁上所有對象的列表
    • number:當前頁的序號,從1開始
    • paginator:當前page對象相關的Paginator對象
  • 方法

    • has_next():如果有下一頁返回True
    • has_previous():如果有上一頁返回True
    • has_other_pages():如果有上一頁或下一頁返回True
    • next_page_number():返回下一頁的頁碼,如果下一頁不存在,拋出InvalidPage異常
    • previous_page_number():返回上一頁的頁碼,如果上一頁不存在,拋出InvalidPage異常
    • len():返回當前頁面對象的個數
      迭代頁面對象:訪問當前頁面中的每個對象

示例代碼

  • 創建視圖pagTest

    from django.core.paginator import Paginator
    
    def pagTest(request, pIndex):
        list1 = AreaInfo.objects.filter(aParent__isnull=True)
        p = Paginator(list1, 10)
        if pIndex == '':
            pIndex = '1'
        pIndex = int(pIndex)
        list2 = p.page(pIndex)
        plist = p.page_range
        return render(request, 'booktest/pagTest.html', {'list': list2, 'plist': plist, 'pIndex': pIndex})
    
  • 配置url url(r'^pag(?P<pIndex>[0-9]*)/$', views.pagTest, name='pagTest'),

  • 定義模板pagTest.html

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
    </head>
    <body>
    <ul>
    {%for area in list%}
    <li>{{area.id}}--{{area.atitle}}</li>
    {%endfor%}
    </ul>
    
    {%for pindex in plist%}
    {%if pIndex == pindex%}
    {{pindex}}&nbsp;&nbsp;
    {%else%}
    <a href="/pag{{pindex}}/">{{pindex}}</a>&nbsp;&nbsp;
    {%endif%}
    {%endfor%}
    </body>
    </html>
    

Django部署(Apache)

  • 使用python3 manage.py runserver來運行服務器,這隻適用測試環境中使用。
  • 正式發佈的服務,我們需要一個可以穩定而持續的服務器,比如Apache, Nginx, IIS等,本文將以Apache爲例。
  • 使用Apache和mod_wsgi部署Django, 是一種久經考驗的將Django投入生產的方法。
  • mod_wsgi是一個Apache模塊, 可以託管任何Python WSGI應用程序, 包括Django。
  • Django將使用任何支持mod_wsgi的Apache版本。

配置步驟

  • Apache2安裝

    Apache2安裝
    sudo apt-get install apache2
    
    # 查看版本
    apachectl -v
    Server version: Apache/2.4.18 (Ubuntu)
    Server built: 2017-09-18T15:09:02
    
  • 確保有127.0.0.1 localhost,沒有就加上

    sudo vim /etc/hosts
    
    127.0.0.1       localhost
    127.0.0.1       www.pyweb.cn
    
  • 打開瀏覽器 輸入 127.0.0.1或localhost

    • 出現 Apache2 Ubuntu Default Page
    • 或It works! 則成功
  • 安裝apache2解析python的包 wsgi程序包

    • $ sudo apt-get install libapache2-mod-wsgi-py3
    • 安裝完成後 進入 /usr/lib/apache2/modules 目錄
    • cd /usr/lib/apache2/modules
    • 查看是否存在mod_wsgi.so-3.5
  • 配置使apache2加載mod-wsgi包

    • 編輯配置文件
    • sudo vim /etc/apache2/apache2.conf
    • 在文件的最後 添加:
    • LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so-3.5
  • 創建網站配置文件

    # 編輯網站配置文件
    sudo vim /etc/apache2/sites-available/myproject.conf
    
    # 配置內容:
    <VirtualHost *:80>
    ServerName www.pyweb.cn
    ServerAdmin [email protected]
    #wsgi文件目錄
    WSGIDaemonProcess python-path=/var/www/myproject
    WSGIScriptAlias / /var/www/myproject/myproject/wsgi.py
    <Directory /var/www/myproject/myproject>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>
    #項目文件目錄
    DocumentRoot /var/www/myproject
    <Directory /var/www/myproject>
        Require all granted
    </Directory>
    #靜態文件目錄
    Alias /static/ /var/www/myproject/static/
    <Directory /var/www/myproject/static/>
        Require all granted
    </Directory>
    #錯誤日誌
    ErrorLog ${APACHE_LOG_DIR}/django-myproject-error.log
    CustomLog ${APACHE_LOG_DIR}/myproject-django.log combined
    </VirtualHost>
    
  • 將當前的配置文件創建一個軟連接到/etc/apache2/sites-enabled

    • $ cd /etc/apache2/sites-enabled
    • $ sudo ln -s ../sites-available/myproject.conf ./
  • 執行命令 生效當前配置

    • $ sudo a2ensite myproject.conf
    • 如果需要讓這個配置失效,可以執行 $ sudo a2dissite myproject.conf
  • 配置Django項目目錄及修改settings.py文件

    • 首先把myproject項目目錄拷貝至 /var/www/目錄下
    • 在將其ALLOWED_HOSTS=[]改爲
    • ALLOWED_HOSTS=[‘www.pyweb.cn’],多個域名可以通過逗號隔開。
  • 修改Django的wsgi.py文件

    import os
    os.environ["DJANGO_SETTINGS_MODULE"] = "myproject.settings"
    #os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pyjfive.settings")
    
    from os.path import join,dirname,abspath
    PROJECT_DIR = dirname(dirname(abspath(__file__)))
    
    import sys # 4
    sys.path.insert(0,PROJECT_DIR)
    
    
    from django.core.wsgi import get_wsgi_application
    application = get_wsgi_application()
    
  • 重啓apache2, $ sudo service apache2 restart

  • 瀏覽器訪問, $ http://www.pyweb.cn/

  • 瀏覽器錯誤 500

    Internal Server Error
    The server encountered an internal error or misconfiguration and was unable to complete your request.
    Please contact the server administrator at [no address given] to inform them of the time this error occurred,
    and the actions you performed just before this error.
    More information about this error may be available in the server error log.
    Apache/2.4.18 (Ubuntu) Server at www.py6web.com Port 80
    
  • 查看apache2的錯誤日誌

    cd /var/log/apache2/
    
    File "/var/www/myproject-test/myproject/wsgi.py", line 17, in <module>, referer: http://www.pyweb.com/
    from django.core.wsgi import get_wsgi_application, referer: http://www.pyweb.com/
    ImportError: No module named 'django', referer: http://www.pyweb.com/
    
  • 問題分析

    進入項目目錄,使用命令 pip3 show Djando 查看當前是否已經安裝django
    ---
    Metadata-Version: 1.1
    Name: Django
    Version: 1.11.8
    
    切換至root用戶 sudo su 
    
    # 進入python3的shell模式
    python3
    #加載django模塊
    import django
    #錯誤:No module named 'django'
    
  • 解決方案

    # 在當前root用戶下 安裝django
    sudo su
    pip3 install django==1.11
    
發佈了410 篇原創文章 · 獲贊 221 · 訪問量 69萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章