参考:https://docs.djangoproject.com/zh-hans/3.0/topics/http/file-uploads/
因为图片也属于静态文件,所以保存到static目录下。
MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")
F:\Test\django-demo\project1>tree /fF:.│ db.sqlite3│ manage.py│├─app1│ │ admin.py│ │ apps.py│ │ models.py│ │ tests.py│ │ urls.py│ │ views.py│ │ __init__.py│ ││ ├─migrations│ │ │ __init__.py│ │ ││ │ └─__pycache__│ │ __init__.cpython-37.pyc│ └─│├─project1│ │ asgi.py│ │ settings.py│ │ urls.py│ │ wsgi.py│ │ __init__.py│ ││ └─│├─static│ ├─css│ ├─images│ ├─js│ └─media│ └─app1└─templates └─app1 index.html
在七章https://blog.csdn.net/u010132177/article/details/103855700
ImageField:继承于FileField,对上传的内容进行校验,确保是有效的图片。
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
可修改migrations文件夹下的0001_initial.py文件名,或删除数据库里的migrations表的对应0001_initial那条
pip install Pillow==3.4.1
将模型类的属性定义成models.ImageField类型。
class PicTest(models.Model): pic = models.ImageField(upload_to='booktest/')
python manage.py makemigrations
python manage.py migrate
如果之前有操作过图书类、英雄类模型创建过数据表,又因为当前没有定义图书、英雄模型类,会提示“是否删除”,输入“no”后回车,表示不删除。
from django.contrib import adminfrom app1.models import PicTest # 【1】导入app1目录下的models文件内的PicTest模型类# Register your models here.admin.site.register(PicTest) # 【2】注册模型类
运行项目:
py manage.py runserver
【1】图片上传必须要设置enctype="multipart/form-data",后台才能接收到数据
【2】post上传别忘记带上验证标识{% csrf_token %}
<!DOCTYPE html><html><head> <title>自定义图片上传</title></head><body> <!-- 【1】图片上传必须要设置enctype="multipart/form-data", 后台才能接收到数据 --> <form method='post' enctype="multipart/form-data" action="/upload_handle/"> {% csrf_token %} {# 【2】post上传别忘记带上验证标识 #} <input type="file" name="pic"><br/> <input type="submit" value="上传"> </form></body></html>
【1-5】
图上上传处理,图片2种类型:
<class ‘django.core.files.uploadedfile.InMemoryUploadedFile‘>
<class ‘django.core.files.uploadedfile.TemporaryUploadedFile‘>
from django.shortcuts import renderfrom django.http import HttpResponsefrom project1.settings import MEDIA_ROOT #导入上传文件保存路径 或 from django.conf import settingsfrom app1.models import PicTest #导入图片模型类# /indexdef index(request): return render(request,'app1/index.html')# /show_uploaddef show_upload(request): '''图片上传页''' return render(request,'app1/upload_pic.html')# /upload_handle# 图上上传处理,图片2种类型:# 小于2.5M放在内存中:<class 'django.core.files.uploadedfile.InMemoryUploadedFile'># 大于2.5放在硬盘上:<class 'django.core.files.uploadedfile.TemporaryUploadedFile'>def upload_handle(request): '''图片上传处理页''' #【1】得到图片 pic=request.FILES['pic'] #【2】拼接图片保存路径+图片名 save_path="%s/app1/%s"%(MEDIA_ROOT,pic.name) #【3】保存图片到指定路径,因为图片是2进制式,因此用wb, with open(save_path,'wb') as f: # pic.chunks()为图片的一系列数据,它是一一段段的,所以要用for逐个读取 for content in pic.chunks(): f.write(content) #【4】保存图片路径到数据库,此处只保存其相对上传目录的路径 PicTest.objects.create(goods_pic='app1/%s'%pic.name) #【5】别忘记返回信息 return HttpResponse('上传成功,图片地址:app1/%s'%pic.name)
"""project1 URL ConfigurationThe `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/3.0/topics/http/urls/Examples:Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home')Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))"""from django.contrib import adminfrom django.urls import pathfrom app1 import viewsurlpatterns = [ path('index/', views.index), path('show_upload/',views.show_upload),# 图片上传页 path('upload_handle/',views.upload_handle),# 图片上传处理页]
上传图片操作后会返回上传成功,及图片地址。
对应目录下也会多一个刚上传的图片。