最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Django自定義圖片和文件上傳路徑(upload_to)的2種方式

 更新時(shí)間:2020年12月01日 10:07:04   作者:大江狗  
這篇文章主要介紹了詳解Django自定義圖片和文件上傳路徑(upload_to)的2種方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

最近在做一個(gè)仿知乎網(wǎng)站的項(xiàng)目了,里面涉及很多圖片和文件上傳。趁此機(jī)會(huì)我給大家總結(jié)下Django自定義圖片和文件上傳路徑的2種方式吧。

方法1: 在Django模型中定義upload_to選項(xiàng)。

Django模型中的ImageField和FileField的upload_to選項(xiàng)是必填項(xiàng),其存儲(chǔ)路徑是相對(duì)于MEIDA_ROOT而來的。

我們來看一個(gè)簡(jiǎn)單案例(如下所示)。如果你的MEDIA_ROOT是/media/文件夾,而你的上傳文件夾upload_to=“avatar", 那么你上傳的文件會(huì)自動(dòng)存儲(chǔ)到/media/avatar/文件夾。

class UserProfile(models.Model):
 
  user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
  avatar = models.ImageField(upload_to='avatar', verbose_name="頭像")

如果你的文件名是sky.jpg, 那么圖片上傳后數(shù)據(jù)庫中的avatar字段為avatar/sky.jpg, 該字段指向圖片對(duì)象,而非絕對(duì)路徑。要在模板中使用該圖片,應(yīng)該使用avatar.url (即/media/avatar/sky.jpg)。

但在實(shí)際應(yīng)用中,請(qǐng)千萬別這么做。這里有2個(gè)嚴(yán)重問題。

  • 所有用戶都把頭像上傳到了同一個(gè)avatar文件夾了
  • 原文件名是什么,那么新文件名就是什么

試想用戶很多,很可能發(fā)生文件重名問題,造成后來用戶上傳的文件把前面用戶上傳的頭像覆蓋了,造成了用戶A掛用戶B頭像的狀況。

正確的做法是動(dòng)態(tài)定義上傳路徑,把圖片存儲(chǔ)到用戶自己的文件夾下,并對(duì)其重命名。如下圖所示。這樣圖片就會(huì)保存在/media/1/avatar/里了,而且文件以u(píng)uid命名。

from django.db import models
from django.contrib.auth.models import User
import uuid
 
# Create your models here.
 
def user_directory_path(instance, filename):
  ext = filename.split('.')[-1]
  filename = '{}.{}'.format(uuid.uuid4().hex[:8], ext)
  # return the whole path to the file
  return "{0}/{1}/{2}".format(instance.user.id, "avatar", filename)
 
class UserProfile(models.Model):
  user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
  avatar = models.ImageField(upload_to=user_directory_path, verbose_name="頭像")

上述案例顯然還有一個(gè)問題,不同系統(tǒng)路徑分隔符/和\是不一樣的,為保證代碼在不同系統(tǒng)中能重用,更好的方式是使用python的os模塊來拼接路徑。如下圖所示。

from django.db import models
from django.contrib.auth.models import User
import uuid
import os
 
# Create your models here.
 
def user_directory_path(instance, filename):
  ext = filename.split('.')[-1]
  filename = '{}.{}'.format(uuid.uuid4().hex[:10], ext)
  # return the whole path to the file
  return os.path.join(instance.user.id, "avatar", filename)
 
class UserProfile(models.Model):
  user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
  avatar = models.ImageField(upload_to=user_directory_path, verbose_name="頭像")

用戶上傳文件可能是圖片,也可能是pdf文件,我們?nèi)绾伟阉鼈兎旁谕挥脩舻牟煌募A下呢?實(shí)現(xiàn)這個(gè)很簡(jiǎn)單,如下圖所示。 

def user_directory_path(instance, filename):
  ext = filename.split('.')[-1]
  filename = '{}.{}'.format(uuid.uuid4().hex[:8], ext)
  sub_folder = 'file'
  if ext.lower() in ["jpg", "png", "gif"]:
    sub_folder = "avatar"
  if ext.lower() in ["pdf", "docx"]:
    sub_folder = "document"
  return os.path.join(instance.user.id, sub_folder, filename)

方法2: 在視圖中自定義上傳圖片或文件路徑

方法1最簡(jiǎn)單直白,但有一個(gè)較大缺陷,文件上傳后未經(jīng)處理就直接存儲(chǔ)了。假如用戶上傳了圖片,我們希望先對(duì)其壓縮或裁剪,然后再存儲(chǔ),或者我們不希望上傳圖片或文件到默認(rèn)的路徑,這時(shí)我們就有必要在視圖中自定義圖片或文件路徑了。例子如下。

@login_required
def ajax_avatar_upload(request):
  user = request.user
  user_profile = get_object_or_404(UserProfile, user=user)
 
  if request.method == "POST":
    form = AvatarUploadForm(request.POST, request.FILES)
    if form.is_valid():
      img = request.FILES['avatar_file'] # 獲取上傳圖片
      cropped_avatar = crop_image(img, user.id)
      user_profile.avatar = cropped_avatar # 將圖片路徑修改到當(dāng)前會(huì)員數(shù)據(jù)庫
     user_profile.save()
  return HttpResponseRedirect(reverse('myaccount:profile'))
 
 
def crop_image(file, uid):
 
  # 隨機(jī)生成新的圖片名,自定義路徑。
  ext = file.name.split('.')[-1]
  file_name = '{}.{}'.format(uuid.uuid4().hex[:10], ext)
  cropped_avatar = os.path.join(uid, "avatar", file_name)
  # 相對(duì)根目錄路徑
  file_path = os.path.join("media", uid, "avatar", file_name)
 
  # 裁剪圖片,壓縮尺寸為200*200。
  img = Image.open(file)
  crop_im = img.crop((50,50,300, 300)).resize((200, 200), Image.ANTIALIAS)
  crop_im.save(file_path)
 
  return cropped_avatar

到此這篇關(guān)于詳解Django自定義圖片和文件上傳路徑(upload_to)的2種方式的文章就介紹到這了,更多相關(guān)Django 上傳路徑內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一篇教程教你學(xué)會(huì)Python進(jìn)制轉(zhuǎn)換(十進(jìn)制轉(zhuǎn)二進(jìn)制、八進(jìn)制、十六進(jìn)制)

    一篇教程教你學(xué)會(huì)Python進(jìn)制轉(zhuǎn)換(十進(jìn)制轉(zhuǎn)二進(jìn)制、八進(jìn)制、十六進(jìn)制)

    計(jì)算機(jī)中只有1和0,所以就導(dǎo)致很多時(shí)候需要進(jìn)制轉(zhuǎn)換,本文介紹了Python進(jìn)制轉(zhuǎn)換,十進(jìn)制轉(zhuǎn)二進(jìn)制,十進(jìn)制轉(zhuǎn)八進(jìn)制,十進(jìn)制轉(zhuǎn)十六進(jìn)制,有興趣的可以了解一下
    2021-05-05
  • Python使用百度通用API進(jìn)行翻譯實(shí)現(xiàn)

    Python使用百度通用API進(jìn)行翻譯實(shí)現(xiàn)

    本文主要介紹了Python使用百度通用API進(jìn)行翻譯實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Python Django實(shí)現(xiàn)layui風(fēng)格+django分頁功能的例子

    Python Django實(shí)現(xiàn)layui風(fēng)格+django分頁功能的例子

    今天小編就為大家分享一篇Python Django實(shí)現(xiàn)layui風(fēng)格+django分頁功能的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • OpenCV-Python實(shí)現(xiàn)凸包的獲取

    OpenCV-Python實(shí)現(xiàn)凸包的獲取

    凸包是一個(gè)計(jì)算幾何中的概念,在圖像處理過程中,我們常常需要尋找圖像中包圍某個(gè)物體的凸包,本文就使用OpenCV實(shí)現(xiàn),感興趣的可以了解一下
    2021-06-06
  • python如何利用plt.legend()添加圖例代碼示例

    python如何利用plt.legend()添加圖例代碼示例

    用python的matplotlib畫圖時(shí),往往需要加圖例說明,下面這篇文章主要給大家介紹了關(guān)于python如何利用plt.legend()添加圖例的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • Python 操作 MongoDB 講解詳細(xì)

    Python 操作 MongoDB 講解詳細(xì)

    MongoDB是一款開源的、基于分布式的、面向文檔存儲(chǔ)的非關(guān)系型數(shù)據(jù)庫。擁有高性能、高可用,易擴(kuò)展的優(yōu)點(diǎn),并且支持豐富的查詢語言來支持讀寫操作以及更復(fù)雜的查詢等。接下來我們來看一下如何使用Python操作MongoDB數(shù)據(jù)庫
    2021-09-09
  • Python環(huán)境配置實(shí)現(xiàn)pip加速過程解析

    Python環(huán)境配置實(shí)現(xiàn)pip加速過程解析

    這篇文章主要介紹了Python環(huán)境配置實(shí)現(xiàn)pip加速過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • python庫skimage給灰度圖像染色的方法示例

    python庫skimage給灰度圖像染色的方法示例

    這篇文章主要介紹了python庫skimage給灰度圖像染色的方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Python實(shí)現(xiàn)arctan換算角度的示例

    Python實(shí)現(xiàn)arctan換算角度的示例

    本文主要介紹了Python實(shí)現(xiàn)arctan換算角度的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • 在Python中居然可以定義兩個(gè)同名通參數(shù)的函數(shù)

    在Python中居然可以定義兩個(gè)同名通參數(shù)的函數(shù)

    今天小編就為大家分享一篇在Python中居然可以定義兩個(gè)同名通參數(shù)的函數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01

最新評(píng)論

福海县| 辽宁省| 湖南省| 来安县| 桂东县| 公主岭市| 阳谷县| 科技| 南木林县| 准格尔旗| 日喀则市| 钟祥市| 衡南县| 卢氏县| 长春市| 万年县| 凤凰县| 新竹县| 德清县| 黎川县| 开江县| 新河县| 淳安县| 寿宁县| 新巴尔虎左旗| 九寨沟县| 开江县| 郁南县| 岱山县| 商丘市| 陇西县| 兰州市| 冕宁县| 大宁县| 文山县| 元江| 金堂县| 邓州市| 永善县| 洪江市| 芒康县|