上节讲的是用原生的上传文件
本节讲django自带的两种上传方式:admin和自制页面的files插入,以及展示图片
并可以对默认路径进行修改
admin上传
写model
class Student5(models.Model):
sno = models.AutoField(primary_key=True)
sname = models.CharField(max_length=30)
photo = models.ImageField(upload_to='imgs')
def __str__(self):
return 'Student3:%s' % self.sname
迁移至我们之前的数据库里
python manage.py makemigrations stu
python manage.py migrate
通过admin页面上传
在管理admin里把该model加入,进入管理页面
admin.site.register(Student5)
新增后看到左上角有新的文件夹和照片,即为我们刚写的imgs
改变默认路径
进setting里,输入global_settings,ctrl进入可以看到有MEDIA_URL和ROOT这两项,将其复制到setting里
#指定上传文件的相对路径(读取文件)
MEDIA_URL = '/media/'
#指定上传文件的存储目录(存储文件)
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
不需要像视频里一样前面增加utf-8
我们在管理页面把刚才的数据删了
再次添加信息,发现照片路径真的加了media
自制页面上传
修改上次的html,提交表单后跳转到upload里,注意最后有斜杠
form action="/stu/upload/"
创建upload的url和view,把上节课的复制过来,获取html传来的信息,插入数据库,即可完成文件上传
path('upload/', views.upload_view),
def upload_view(request):
uname = request.POST.get('uname', '')
photo = request.FILES.get('photo', '')
# 入库操作
Student5.objects.create(sname=uname, photo=photo)
return HttpResponse('上传成功!')
可以查看跟刚才一样的效果
展示图片
新建视图的path和view,将model的值传递给新的网页,循环输出
path('show_all/', views.show_all_view),
def show_all_view(request):
stus = Student5.objects.all()
return render(request, 'show_all.html', {'stus': stus})
<table border="1" cellspacing="0" width="500px">
<tr>
<th>编号</th>
<th>姓名</th>
<th>头像</th>
<th>操作</th>
</tr>
{% for stu in stus %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ stu.sname }}</td>
<td><img style="width: 200px;" src="/media/{{ stu.photo }}"/></td>
<td>
下载
</td>
</tr>
{% endfor %}
</table>
网页图片路由配置
其中照片要用img标签,src写上相对路径
但是还找不到,因为照片超链接的前面/media并没有配置过路由
需要在项目根路由url里增加,用到了一个新的方法:serve读取图片
serve是个视图函数,点进去发现他有四个参数
def serve(request, path, document_root=None, show_indexes=False):
request视图、path是路径,document_root是绝对路径
这段代码传递路径和字典参数给serve,实现了将路径给网页视图的功能
from .settings import DEBUG,MEDIA_ROOT
from django.views.static import serve
if DEBUG:
urlpatterns += re_path(r'^media/(?P<path>.*)/$', serve, {"document_root": MEDIA_ROOT}),
urlpatterns是个列表,可以追加
?P是之前讲的关键字传参,用于确定多个传递参数的赋值顺序
.*是正则表达式,0或多次,表示任意字符
$表示字符
后面字典是上次学的自带参数
网页相对路径配置
src="/media/{{ stu.photo }}“也可以换成
src=”{{ MEDIA_URL }}{{ stu.photo }}"
但是还不成功,因为网页找不到MEDIA_URL这个值,还需要改一个地方:
在templates里的选项里,context处理器,增加一行media
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.template.context_processors.media'
],
},
},
]
就成功了,可以用ctrl看出来,media的源代码就是输出一个字典,也就是我们文章开始定义的MEDIA_URL
def media(request):
"""
Add media-related context variables to the context.
"""
return {'MEDIA_URL': settings.MEDIA_URL}