Django 管理图片
图片的上传
1.模型定义 model.py
class Image(models.Model):
image = models.ImageField(upload_to='images/%Y%m%d')
class Meta:
db_table = 'image'
verbose_name = '图片'
verbose_name_plural = verbose_name
2.注册到管理后台 admin.py
@admin.register(Image)
class ImageAdmin(admin.ModelAdmin):
list_display = ('image',)
这时,在后台就可以实现图片的上传了,显然不是我们想要的,我们是想在前端HTML页面上实现图片上传。
接下来:
3.前端页面
<form action="{% url 'article:uploads' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="col-md-6 offset-md-3">
<input type="file" name="file_field" multiple="multiple" required="required">
</div>
<div class="col-md-6 offset-md-3">
</div>
<div class="modal-footer">
<input class="btn btn-info" type="submit" value="提交">
</div>
</form>
- enctype="multipart/form-data" 允许表单提交文件,必须写这一项。multiple="multiple" 允许一次提交多个文件。
这里只需要选择图片的时候,Windows电脑按着Ctrl键。
4.views.py
def uploads_files(request):
if request.method == 'POST':
files = request.FILES.getlist('file_field')
for f in files:
file = Image(image=f)
file.save()
return redirect(reverse('article:add_article'))
else:
return
5.路由配置
path('uploads/', views.uploads_files, name='uploads'),
6.setting.py
必须配置
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
7.运行后,打开上传的图片页面,这里我是在博客中插入的,可以根据自己的需求更改路径.
支持多张图片同时上传


admin后台管理图片。
在后台管理图片的时候,虽然可以查看图片,不过需要点击,很麻烦。
优化:
1.修改model.py
增加部分内容
from django.utils.html import format_html
class Image(models.Model):
....
....
def admin_image(self):
return format_html(
'<img src="{}" width="100px"/>',
self.image.url,
)
admin_image.short_description = u'图片'
admin_image.allow_tags = True
2.admin.py后台添加字段admin_image
@admin.register(Image)
class ImageAdmin(admin.ModelAdmin):
list_display = ('image', 'admin_image',)
这样,我们就可以实现后台显示图片的缩略图了

文件或图片的上传位置和删除问题
你以为完了吗,不,还能优化,不信你删除一下试试,只是数据没了,但是文件还存在,这种情况需要优化。
model.py
增加
from django.db.models.signals import post_delete
from django.dispatch import receiver
import os
# 重写删除文件功能,数据删除的时候,文件也跟随删除
@receiver(post_delete, sender=Image)
def delete_upload_files(sender, instance, **kwargs):
files = getattr(instance, 'image', '')
if not files:
return
fname = os.path.join(settings.MEDIA_ROOT, files.name)
if os.path.isfile(fname):
os.remove(fname)
重写上传位置
def upload_to_con(instance, filename):
return '/'.join(
[MEDIA_ROOT, 'article_insert' + instance.image.url, filename])
class Image(models.Model):
image = models.ImageField(upload_to=upload_to_con)
迁移数据,就ok了
文章评论