###第4部分###
源代码地址:djProject: 这是我入门Django用的项目,其中功能包含有项目初始化设置、mysql的数据库建立、增删改查、图片的上传与显示等等
上传图片并保存路径到数据库
参考网址:Django上传图片
我的目标是将图片上传,用作User的头像。
先给大家看文件结构图:
- 在
models.py
下加入一行:
upload_to
是在设置好的的media文件夹下再创建users文件夹。
classUser(models.Model):"""
创建用户表
"""# ...省略其他属性# 下面是加入的
avatar = models.ImageField(upload_to='users', max_length=100, blank=True, null=True, verbose_name='用户头像')
- 在settings.py下加入代码,
MEDIA_URL、MEDIA_ROOT
的具体作用在下面官方指南中给出:
#上传图片# media_confige
MEDIA_URL ='/media/'
MEDIA_ROOT = BASE_DIR /'static/media'
- 在模版文件夹下添加
add_user_image.html
:
主要是注意
enctype='multipart/form-data' method="post"
<formaction="{% url 'users:upload_handle'%}"enctype='multipart/form-data'method="post">
{% csrf_token %}
<p>选择图片:<inputtype="file"name="pic"></p><p><inputtype="submit"value="上传头像"></p></form>
- 老样子,
urls.py
和views.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
defadd_user_image(request):return render(request,'users/add_user_image.html')defupload_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()withopen(where,'wb')as f:for i in content:
f.write(i)# 上传文件名称到数据库
User.objects.filter(name='trent').update(avatar=new_name)# 返回的httpresponsereturn HttpResponse('ok')
对了,我在utils文件夹中写了一个
uploads.py
。里面有一个生成随机名字的代码,在这里贴出来:
import time
import numpy as np
defgetNewName(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/
在模型中使用 FileField 或 ImageField (见下文)需要几个步骤:
- 在你的配置文件中,你需要定义 MEDIA_ROOT 作为你希望 Django 存储上传文件的目录的完整路径。(为了保证性能,这些文件不存储在数据库中。)定义 MEDIA_URL 作为该目录的基本公共 URL。确保这个目录是 Web 服务器的用户账号可以写的。
- 将 FileField 或 ImageField 添加到你的模型中,定义 upload_to 选项,指定 MEDIA_ROOT 的子目录,用于上传文件。
- 所有这些将被存储在你的数据库中的是一个文件的路径(相对于 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
目录下。
如果你想检索上传文件的盘上文件名,或者文件的大小,可以分别使用 name 和 size 属性;关于可用属性和方法的更多信息,请参见 File 类参考和 管理文件 主题指南。
展示图片
参考文献:Django显示图片:MEDIA_ROOT和MEDIA_URL的设置
- 设置MEDIA_URL和MEDIA_ROOT,如果上面的“上传图片”功能已经实现了那这里已经设置好了
#上传图片# media_config
MEDIA_URL ='/media/'
MEDIA_ROOT = BASE_DIR /'static/media'
- 在项目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)# 主要是上面那行
- 在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/
结果如下:
如果要利用数据库中的图片名称来进行展示,下面是具体实现
- 在urls.py下添加代码:
path('show_avatar/', views.show_avatar, name='show_avatar'),
- 在views.py下添加代码:
defshow_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})
- 在show_avatar.html下添加代码:
<p>{{ avatar_info.userName }}</p><imgsrc="{{ avatar_info.avatarUrl }}"/>
结果图:
参考文献
- Django上传图片、Django显示文件:MEDIA_ROOT和MEDIA_URL的设置
版权归原作者 小明2766 所有, 如有侵权,请联系我们删除。