【Django入门手册】04 上传图片并保存路径到数据库、展示图片

###第4部分###

源代码地址:djProject: 这是我入门Django用的项目,其中功能包含有项目初始化设置、mysql的数据库建立、增删改查、图片的上传与显示等等

上传图片并保存路径到数据库

参考网址:Django上传图片

我的目标是将图片上传,用作User的头像。

先给大家看文件结构图:

在这里插入图片描述

  1. models.py下加入一行:

upload_to是在设置好的的media文件夹下再创建users文件夹。

class User(models.Model):
    """
    创建用户表
    """
	# ...省略其他属性
    # 下面是加入的
    avatar = models.ImageField(upload_to='users', max_length=100, blank=True, null=True, verbose_name='用户头像')
  1. 在settings.py下加入代码,MEDIA_URL、MEDIA_ROOT的具体作用在下面官方指南中给出:
#上传图片
# media_confige
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'static/media'
  1. 在模版文件夹下添加add_user_image.html

主要是注意enctype='multipart/form-data' method="post"

<form action="{% url 'users:upload_handle'%}" enctype='multipart/form-data' method="post">
    {% csrf_token %}
    <p>选择图片:<input type="file" name="pic"></p>
    <p><input type="submit" value="上传头像"></p>
</form>
  1. 老样子,urls.pyviews.py分别写代码:
    # 第一行用来转到填表单,第二行用来处理上传来的图片
    path('add_user_image/', views.add_user_image, name='add_user_image'),
    path('upload_handle/', views.upload_handle, name='upload_handle'),
from utils.uploads import getNewName
from .models import User
from django.conf import settings

def add_user_image(request):
    return render(request, 'users/add_user_image.html')

def upload_handle(request):
    # 获取一个文件管理器对象
    file = request.FILES['pic']

    # 保存文件
    new_name = getNewName('avatar') # 具体实现在自己写的uploads.py下
	# 将要保存的地址和文件名称
    where = '%s/users/%s' % (settings.MEDIA_ROOT, new_name)
    # 分块保存image
    content = file.chunks()
    with open(where, 'wb') as f:
        for i in content:
            f.write(i)

    # 上传文件名称到数据库
    User.objects.filter(name='trent').update(avatar=new_name)
    # 返回的httpresponse
    return HttpResponse('ok')

对了,我在utils文件夹中写了一个uploads.py。里面有一个生成随机名字的代码,在这里贴出来:

import time
import numpy as np

def getNewName(file_type):
    # 前面是file_type+年月日时分秒
    new_name = time.strftime(file_type+'-%Y%m%d%H%M%S', time.localtime())
    # 最后是5个随机数字
    # Python中的numpy库中的random.randint(a, b, n)表示随机生成n个大于等于a,小于b的整数
    ranlist = np.random.randint(0, 10, 5)
    for i in ranlist:
        new_name += str(i)
    # 加后缀名
    new_name += '.jpg'
    # 返回字符串
    return new_name

最后,在数据库中也显示了文件名称:

在这里插入图片描述

官网MEDIA_ROOT和upload_to指南:https://docs.djangoproject.com/zh-hans/3.2/ref/models/fields/

在模型中使用 FileFieldImageField (见下文)需要几个步骤:

  1. 在你的配置文件中,你需要定义 MEDIA_ROOT 作为你希望 Django 存储上传文件的目录的完整路径。(为了保证性能,这些文件不存储在数据库中。)定义 MEDIA_URL 作为该目录的基本公共 URL。确保这个目录是 Web 服务器的用户账号可以写的。
  2. FileFieldImageField 添加到你的模型中,定义 upload_to 选项,指定 MEDIA_ROOT 的子目录,用于上传文件。
  3. 所有这些将被存储在你的数据库中的是一个文件的路径(相对于 MEDIA_ROOT )。你很可能要使用 Django 提供的方便的 url 属性。例如,如果你的 ImageField 叫做 mug_shot,你可以在模板中使用 {{ object.mug_shot.url }} 获取图片的绝对路径。

例如,你的 MEDIA_ROOT 设置为 '/home/media'upload_to 设置为 'photos/%Y/%m/%d'upload_to 中的 '%Y/%m/%d' 部分是 strftime() 格式化,'%Y' 是四位数的年,'%m' 是两位数的月,'%d' 是两位数的日。如果你在 2007 年 1 月 15 日上传了一个文件,它将被保存在 /home/media/photos/2007/01/15 目录下。

如果你想检索上传文件的盘上文件名,或者文件的大小,可以分别使用 namesize 属性;关于可用属性和方法的更多信息,请参见 File 类参考和 管理文件 主题指南。

展示图片

参考文献:Django显示图片:MEDIA_ROOT和MEDIA_URL的设置

  1. 设置MEDIA_URL和MEDIA_ROOT,如果上面的“上传图片”功能已经实现了那这里已经设置好了
#上传图片
# media_config
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'static/media'
  1. 项目Project的urls.py添加代码:
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    path('web/', include('web.urls')),
    path('admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
# 主要是上面那行
  1. 在settings文件中,TEMPLATES中'context_processors'下面新增'django.template.context_processors.media'
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates']
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                # ...
                # 加下面这行
                'django.template.context_processors.media',
            ],
        },
    },
]

配置好后可以使用浏览器访问上传的文件,比如MEDIA_URL设置的是/media/MEDIA_ROOT设置的是/Users/trent2766/code/pcPyCode/djStore/djProject/static/media/,在models中设置的文件上传到upload_to = “users”。

那么文件上传后实际存储地址为/Users/trent2766/code/pcPyCode/djStore/djProject/static/media/users,URL为:127.0.0.1:8000/media/users/

结果如下:

在这里插入图片描述

如果要利用数据库中的图片名称来进行展示,下面是具体实现

  1. 在urls.py下添加代码:
path('show_avatar/', views.show_avatar, name='show_avatar'),
  1. 在views.py下添加代码:
def show_avatar(request):
    user = User.objects.filter(name='trent')[0]
    avatarName = str(user.avatar)
    # avatarUrl = '%s/users/%s' % (settings.MEDIA_URL, avatarName) # 另一种写法
    avatarUrl = os.path.join(settings.MEDIA_URL, 'users', avatarName)
    avatar_info = {'userName':'trent', 'avatarUrl': avatarUrl}
    return render(request, 'users/show_avatar.html', {'avatar_info':avatar_info})
  1. 在show_avatar.html下添加代码:
<p>{{ avatar_info.userName }}</p>
<img src="{{  avatar_info.avatarUrl }}"/>

结果图:

在这里插入图片描述

参考文献

  1. Django上传图片Django显示文件:MEDIA_ROOT和MEDIA_URL的设置
  • 15
    点赞
  • 111
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值