十九. 增加一個項目協作留言板功能(五)----- 增加添加附件功能

在任務管理中,我們增加一個添加附件的功能,方便用戶將相應的資料上傳至服務器。Django提供了方便的upload方法,具體可參閱https://docs.djangoproject.com/en/1.9/topics/http/file-uploads/



1. 建立上傳附件的Form:
#建立上傳附件的FORM
class UploadFileForm(forms.Form):
    #提供一個上傳附件的FORM
    file = forms.FileField()

2.  建立一個uploadmodel:

Models.py:

#上傳附件
class Upload(models.Model):
    #與task表格是一對多的關係,依附於task之上
    task = models.ForeignKey(Task)
    #上傳附件名稱
    upload_title = models.CharField(max_length=255)
    #上傳附件路徑
    upload_path = models.CharField(max_length=255)
    #上傳附件時間
    upload_signtime = models.DateTimeField(auto_now_add=True,null=True)

    def __unicode__(self):
        return self.upload_title

3 .建立一個echo目錄下建立一個upload.py文件用來處理上傳文件

通常會使用下面的兩個個方法來訪問被上傳的內容:
UploadedFile.read():從文件中讀取整個上傳的數據。小心整個方法:如果這個文件很大,你把它讀到內存中會弄慢你的系統。
UploadedFile.multiple_chunks():如果上傳的文件足夠大需要分塊就返回真。默認的這個值是2.5兆,當然這個值是可以調節的,看下面的UploadedFile.chunks():一個產生器,返回文件的塊。如果multiple_chunks()是真的話,你應該在一個循環中使用這個方法,而不是使用read();

我們使用第二種方法來進行處理

Upload.py

# -*- coding: UTF-8 -*-
import os,sys
reload(sys)
sys.setdefaultencoding('utf8')

#定義一個處理上傳文件的函數
def handle_uploaded_file(f):
    #獲取項目的基本路徑
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

    try:
        #將上傳文件放於media路徑下
        #注意: media前面的'/'與否取決於windows或linux平臺
        path = os.path.join(BASE_DIR, 'media/')
        #如果沒有這個路徑則建立
        if not os.path.exists(path):
            os.makedirs(path)
        else:
            file_name = str(path + f.name)
            #以二進制寫方式打開,可以讀、寫文件, 如果文件不存在,創建該文件;如果文件已存在,先清空,再打開文件
            destination = open(file_name, 'wb+')
            #在UploadedFile.chunks()上循環而不是用read(),保證大文件不會大量使用你的系統內存。
            for chunk in f.chunks():
                destination.write(chunk)
            destination.close()
    except Exception, e:
        print e

    #返回文件名稱及路徑
    return f.name, path

3.      views.py中建立一個上傳文件的函數:

#上傳附件函數
def upload_file(request, pk):
    #獲得一個任務的實例
    task_ins = get_object_or_404(Task, pk=pk)

    #如果獲取到了POST的提交
    if request.method == 'POST':
        #獲取form表單,request.FILES是存放文件的地方
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            #通過處理上傳文件函數來獲得返回值
            uf = handle_uploaded_file(request.FILES['file'])

            #獲取上傳文件的實例,並補充相應信息至數據庫中
            upload_ins = Upload()
            #綁定相應的task id
            upload_ins.task_id = task_ins.id
            #記錄相應的文件名
            upload_ins.upload_title = uf[0]
            #記錄相應的上傳路徑
            upload_ins.upload_path = uf[1]
            #保存upload的實例
            upload_ins.save()
            return redirect('task_edit', pk=task_ins.id)
    else:
        form = UploadFileForm()

    #構建相應的context,傳遞至上傳文件頁面
    context = {
        'form': form,
        'sub_title': '上傳文件',

    }
    return render(request, 'upload.html', context)

4.      建立一個上傳文件的html頁面,用於上傳文件:

Upload.html:

{%  extends "index.html" %}
{% block page_title %}
    上傳文件
{% endblock %}
{% block container %}
{% load staticfiles %}


<form enctype="multipart/form-data" method="POST" action="">{% csrf_token %}

    {{ form }}
   <input type="submit" value="上傳文件" />
</form>

{% endblock %}

5.      在原有任務表單中,增加上傳附件的鏈接:

<!-----附件上傳頁面 BEGIN----->
      <div id="div_id_task_attachment" class="form-group">
          <label for="div_id_task_attachment" class="control-label"><strong>附件</strong></label>
      </div>
      <div>
      <!--通過數據庫,將upload中附件的數據取出,並展示-->
              {% for data in task.upload_set.all %}
                  <!--get_media_prefix 在settings.py中定義,獲取相關路徑,並顯示相應文件名-->
                  <a href="{% get_media_prefix %}{{ data.upload_title }}">{{ data.upload_title }}</a><br/>
              {% endfor %}
      <br/><br/>
      </div>
      <!---附件上傳頁面 end---->

  <!--如果任務的狀態是處理中,那麼以下按鈕正常出現,如果是其他狀態,那麼這些按鈕不出現-->
      {% if task.task_status == '處理中' %}

  <div>
      <a href="{% url 'upload_file' task.id %}  "><input class='btn btn-purple' type='button' value='添加附件' /></a>

  </div>
  {% endif %}
      <br/><br/>

6.      增加urls.py中的信息:

#上傳附件
urlpatterns = [
…
url(r'^upload_file/(?P<pk>\d+)/$', echo.views.upload_file, name='upload_file'),
…
]

7.      調整urls.py關於靜態文件的配置

在生產環境中, 靜態文件交由Web服務器處理,Django本身不處理靜態文件。爲了便於開發,Django提供了在開發環境的對靜態文件的處理機制。

1)在INSTALLED_APPS裏面加入'django.contrib.staticfiles',

2urls.py裏面加入

if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

MEDIA:指用戶上傳的文件,比如在Model裏面的FileFIeldImageField上傳的文件。

STATIC主要指的是如css,js,images這樣文件


8.      驗證上傳附件功能

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章