Django 模型 ImageField 字段的使用

一猾担、系統(tǒng)環(huán)境

  • deepin 15.10.2 桌面版 64位
  • PyCharm Professional 2019.1.2
  • Django 2.2.4
  • Python 3.7.4

二掘鄙、基本概念

class ImageField(upload_to = None, height_field = None, width_field = None, max_length = 100, **options)[source]

ImageField 是用于保存圖像文件的字段糊饱。其基本用法和特性與 FileField 一樣对竣,只不過多了兩個屬性 height_field 和 width_field,分別保存圖片的高度和寬度信息笔喉。默認(rèn)情況下尸诽,該字段在 HTML 中表現(xiàn)為一個 ClearableFileInput 標(biāo)簽。在數(shù)據(jù)庫內(nèi)绑改,我們實際保存的是一個字符串類型谢床,默認(rèn)最大長度 100,可以通過 max_length 參數(shù)自定義厘线。真實的圖片是保存在服務(wù)器的文件系統(tǒng)內(nèi)的识腿。

三、使用步驟

  • 配置 settings.py
# settings.py

# 配置 MEDIA_ROOT 作為你上傳文件在服務(wù)器中的基本路徑
MEDIA_ROOT = os.path.join(BASE_DIR, 'upload') # 注意此處不要寫成列表或元組的形式
# 配置 MEDIA_URL 作為公用 URL造壮,指向上傳文件的基本路徑
MEDIA_URL = '/media/'
# 這里特意寫成 upload 和 media渡讼,而不是統(tǒng)一寫成 media 或 upload,是為了便于理解 MEDIA_ROOT 和 MEDIA_URL 的作用和區(qū)別
  • models.py 中設(shè)置 ImageField 字段
# models.py

def user_directory_path(instance, filename):
    ext = filename.split('.').pop()
    filename = '{0}{1}.{2}'.format(instance.name, instance.identity_card, ext)
    return os.path.join(instance.major.name, filename) # 系統(tǒng)路徑分隔符差異耳璧,增強代碼重用性

class Student(models.Model):
    major = models.ForeignKey(Major, on_delete = models.CASCADE)
    name = models.CharField('姓名', max_length = 10)
    identity_card = models.CharField('身份證號', max_length = 20, unique = True)
    ......    
    # upload_to 參數(shù)接收一個回調(diào)函數(shù) user_directory_path成箫,該函數(shù)返回具體的路徑字符串,圖片會自動上傳到指定路徑下旨枯,即 MEDIA_ROOT + upload_to
    # user_directory_path 函數(shù)必須接收 instace 和 filename 兩個參數(shù)蹬昌。參數(shù) instace 代表一個定義了 ImageField 的模型的實例,說白了就是當(dāng)前數(shù)據(jù)記錄攀隔;filename 是原本的文件名
    # null 是針對數(shù)據(jù)庫而言皂贩,如果 null = True, 表示數(shù)據(jù)庫的該字段可以為空;blank 是針對表單的昆汹,如果 blank = True明刷,表示你的表單填寫該字段的時候可以不填,但是對數(shù)據(jù)庫來說筹煮,沒有任何影響
    photo = models.ImageField('照片', upload_to = user_directory_path, blank = True, null = True)
    ......
    # 這里定義一個方法遮精,作用是當(dāng)用戶注冊時沒有上傳照片,模板中調(diào)用 [ModelName].[ImageFieldName].url 時賦予一個默認(rèn)路徑    
    def photo_url(self):
        if self.photo and hasattr(self.photo, 'url'):
            return self.photo.url
        else:
            return '/media/default/user.jpg'
  • 配置 urls.py
# 注意是項目根路由 urls.py 文件,而不是應(yīng)用中的二級路由 urls.py 文件

# 方法一:
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    ......    
] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)

# 方法二:
from django.urls import re_path
from django.conf import settings
from django.views.static import serve

urlpatterns = [
    ......
    # 注意是 media 而不是 upload
    re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),    
]
  • 配置 views.py
# views.py
from django.shortcuts import get_object_or_404
from .models import Major

def add_student(request):
    if request.method == 'POST':
        major = get_object_or_404(Major, pk = request.POST['major'])
        major.student_set.create(
            ......            
            photo = request.FILES.get('photo'),
        )
        ......
    ......
  • 模板中呈現(xiàn)圖片
<!-- 調(diào)用的是 Student 模型中的 photo_url 方法本冲,而不是直接調(diào)用 Student.photo.url准脂。如果用戶在注冊時沒有上傳照片,后者會報錯 -->
<img id="photo" src="{{ student.photo_url }}">

四檬洞、django-imagekit 的使用

imagekit 可以實現(xiàn)對上傳圖片的大小狸膏、質(zhì)量、格式添怔、水印湾戳、去邊框等進行定制,功能很強大广料。

  • 準(zhǔn)備工作
pip install pillow
pip install django-imagekit
# settings.py

INSTALLED_APPS = [
    'myapp',
    'imagekit', # 注冊 imagekit
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
  • 配置 models.py
# models.py

from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToFill
......

class Student(models.Model):
    ...... 
    photo = models.ImageField('照片', upload_to = user_directory_path, blank = True, null = True)
    photo_295_413 = ImageSpecField( # 注意:ImageSpecField 不會生成數(shù)據(jù)庫表的字段
        source = 'photo',
        processors = [ResizeToFill(295, 413)],  # 處理成一寸照片的大小
        format = 'JPEG',  # 處理后的圖片格式
        options = {'quality': 95}  # 處理后的圖片質(zhì)量
    )
    ......
    def photo_295_413_url(self):
        if self.photo_295_413 and hasattr(self.photo_295_413, 'url'):
            return self.photo_295_413.url
        else:
            return '/media/default/user.jpg'
# 默認(rèn)情況下砾脑,imagekit 使用 imagekit.cachefiles.namers.source_name_as_path 來生成圖片的路徑
# 上例定制后的圖片會上傳到 [MEDIA_ROOT]/CACHE/images/[upload_to]/[md5處理后的名字.jpg]
# 想要自定義路徑請參考 https://blog.csdn.net/weixin_42368421/article/details/84955946
  • 模板中呈現(xiàn)圖片
<img id="photo" src="{{ student.photo_295_413_url }}">
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市艾杏,隨后出現(xiàn)的幾起案子韧衣,更是在濱河造成了極大的恐慌,老刑警劉巖购桑,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件畅铭,死亡現(xiàn)場離奇詭異,居然都是意外死亡勃蜘,警方通過查閱死者的電腦和手機硕噩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缭贡,“玉大人炉擅,你說我怎么就攤上這事≡裙椋” “怎么了坑资?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長穆端。 經(jīng)常有香客問我袱贮,道長,這世上最難降的妖魔是什么体啰? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任攒巍,我火速辦了婚禮,結(jié)果婚禮上荒勇,老公的妹妹穿的比我還像新娘柒莉。我一直安慰自己,他們只是感情好沽翔,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布兢孝。 她就那樣靜靜地躺著窿凤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪跨蟹。 梳的紋絲不亂的頭發(fā)上雳殊,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機與錄音窗轩,去河邊找鬼夯秃。 笑死,一個胖子當(dāng)著我的面吹牛痢艺,可吹牛的內(nèi)容都是我干的仓洼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼堤舒,長吁一口氣:“原來是場噩夢啊……” “哼色建!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起植酥,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤镀岛,失蹤者是張志新(化名)和其女友劉穎弦牡,沒想到半個月后友驮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡驾锰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年卸留,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片椭豫。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡耻瑟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赏酥,到底是詐尸還是另有隱情喳整,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布裸扶,位于F島的核電站框都,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏呵晨。R本人自食惡果不足惜魏保,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望摸屠。 院中可真熱鬧谓罗,春花似錦、人聲如沸季二。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至刻蚯,卻和暖如春蜂筹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背芦倒。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工艺挪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人兵扬。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓麻裳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親器钟。 傳聞我的和親對象是個殘疾皇子津坑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容