Django 模型 ImageField 字段的使用

一、系统环境

  • 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,分别保存图片的高度和宽度信息。默认情况下,该字段在 HTML 中表现为一个 ClearableFileInput 标签。在数据库内,我们实际保存的是一个字符串类型,默认最大长度 100,可以通过 max_length 参数自定义。真实的图片是保存在服务器的文件系统内的。

三、使用步骤

  • 配置 settings.py
# settings.py

# 配置 MEDIA_ROOT 作为你上传文件在服务器中的基本路径
MEDIA_ROOT = os.path.join(BASE_DIR, 'upload') # 注意此处不要写成列表或元组的形式
# 配置 MEDIA_URL 作为公用 URL,指向上传文件的基本路径
MEDIA_URL = '/media/'
# 这里特意写成 upload 和 media,而不是统一写成 media 或 upload,是为了便于理解 MEDIA_ROOT 和 MEDIA_URL 的作用和区别
  • models.py 中设置 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) # 系统路径分隔符差异,增强代码重用性

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 参数接收一个回调函数 user_directory_path,该函数返回具体的路径字符串,图片会自动上传到指定路径下,即 MEDIA_ROOT + upload_to
    # user_directory_path 函数必须接收 instace 和 filename 两个参数。参数 instace 代表一个定义了 ImageField 的模型的实例,说白了就是当前数据记录;filename 是原本的文件名
    # null 是针对数据库而言,如果 null = True, 表示数据库的该字段可以为空;blank 是针对表单的,如果 blank = True,表示你的表单填写该字段的时候可以不填,但是对数据库来说,没有任何影响
    photo = models.ImageField('照片', upload_to = user_directory_path, blank = True, null = True)
    ......
    # 这里定义一个方法,作用是当用户注册时没有上传照片,模板中调用 [ModelName].[ImageFieldName].url 时赋予一个默认路径    
    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 文件,而不是应用中的二级路由 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.*)$', 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'),
        )
        ......
    ......
  • 模板中呈现图片


四、django-imagekit 的使用

imagekit 可以实现对上传图片的大小、质量、格式、水印、去边框等进行定制,功能很强大。

  • 准备工作
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 不会生成数据库表的字段
        source = 'photo',
        processors = [ResizeToFill(295, 413)],  # 处理成一寸照片的大小
        format = 'JPEG',  # 处理后的图片格式
        options = {'quality': 95}  # 处理后的图片质量
    )
    ......
    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'
# 默认情况下,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
  • 模板中呈现图片

你可能感兴趣的:(Django 模型 ImageField 字段的使用)