一猾担、系統(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 }}">