文件上傳
就這么六步!
一、settings配置文件中配置
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'medias').replace('\\', '/')#media即為圖片上傳的根路徑
二、url路由中配置
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index,name='index'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) #如果單純的是上傳,文件並不用來顯示或者讀取,就不用加這個
三、models.py文件中的寫法
class Book(models.Model):
name = models.CharField(max_length=32)
date1 = models.DateTimeField(auto_now=True,null=True)
date2 = models.DateTimeField(auto_now_add=True,null=True)
img = models.ImageField(upload_to='img',null=True) #寫上upload_to,后面指定一個路徑,那么將來上傳的文件會直接生成到配置文件中的那個medias文件夾中的img文件夾中,不需要我們自己寫讀取文件內容寫入本地文件的操作,django內部幫我們自動處理了
四、views視圖函數中的寫法,上傳一個圖片:
def index(request):
if request.method == 'POST':
print(request.POST)
username = request.POST.get('username')
print('files',request.FILES)
file_obj = request.FILES.get('file')
models.Book.objects.create(
name=username,
img=file_obj,
) #自動就會將文件上傳到我們配置的img文件夾中
return render(request,'index.html')
五、更新上傳了的文件(注意,只是會更新數據庫中那個字段保存的文件的路徑,但是之前上傳的文件是不會被自動刪除的,需要我們自行再寫邏輯來刪除之前上傳錯的或者需要被覆蓋的文件。還有就是如果上傳的文件名稱是相同的那么你會發現數據庫中這個字段的路徑后面的文件名稱會出現一個亂起八糟的隨機字符串,這是因為上傳的文件名稱沖突了,django為了解決這個沖突,給你改了一下你的文件名稱。)
obj = models.Book.objects.get(name='chao2')
obj.img=file_obj
obj.save()
#下面的update方法是不能更新正確更新保存的文件路徑的,除非我們自己手動拼接文件路徑,然后img=路徑來進行update更新
models.Book.objects.filter(name='chao2').update(img=file_obj)
六、查看已經上傳了的文件(就需要借助我們上面在settings配置文件中和url中的配置了)
views.py視圖函數的寫法:
def index(request):
objs = models.Book.objects.all()
return render(request,'index.html',{'objs':objs})
index.html文件中的寫法:
<div>
{% for obj in objs %}
<img src="/media/{{ obj.img }}" alt="">
{% endfor %}
</div>
<div>
{% for obj in objs %}
<img src="/media/{{ obj.img }}" alt="">
<!--<img src="/media/{{ obj.img.name }}" alt="">-->
{% endfor %}
</div>
文件下載
在實際的項目中很多時候需要用到下載功能,如導excel、pdf或者文件下載,當然你可以使用web服務自己搭建可以用於下載的資源服務器,如nginx,這里我們主要介紹django中的文件下載。
我們這里介紹三種Django下載文件的簡單寫法,然后使用第三種方式,完成一個高級一些的文件下載的方法
index.html內容如下
<div>
<a href="{% url 'download' %}">文件下載</a>
</div>
urls.py文件內容如下:
urlpatterns = [
url(r'^index/', views.index,name='index'),
url(r'^download/', views.download,name='download'),
]
view視圖函數的寫法有一下三種:
方式1:
from django.shortcuts import HttpResponse
def download(request):
file = open('crm/models.py', 'rb') #打開指定的文件
response = HttpResponse(file) #將文件句柄給HttpResponse對象
response['Content-Type'] = 'application/octet-stream' #設置頭信息,告訴瀏覽器這是個文件
response['Content-Disposition'] = 'attachment;filename="models.py"' #這是文件的簡單描述,注意寫法就是這個固定的寫法
return response
注意:HttpResponse會直接使用迭代器對象,將迭代器對象的內容存儲城字符串,然后返回給客戶端,同時釋放內存。可以當文件變大看出這是一個非常耗費時間和內存的過程。而StreamingHttpResponse是將文件內容進行流式傳輸,數據量大可以用這個方法
方式2:
from django.http import StreamingHttpResponse #
def download(request):
file=open('crm/models.py','rb')
response =StreamingHttpResponse(file)
response['Content-Type']='application/octet-stream'
response['Content-Disposition']='attachment;filename="models.py"'
return response
方式3:
from django.http import FileResponse
def download(request):
file=open('crm/models.py','rb')
response =FileResponse(file)
response['Content-Type']='application/octet-stream'
response['Content-Disposition']='attachment;filename="models.py"'
return response
三種http響應對象在django官網都有介紹.入口:https://docs.djangoproject.com/en/1.11/ref/request-response/
推薦使用FileResponse,從源碼中可以看出FileResponse是StreamingHttpResponse的子類,內部使用迭代器進行數據流傳輸。