这时,在后台就可以实现图片的上传了,显然不是我们想要的,我们是想在前端HTML页面上实现图片上传。
接下来:
前端页面 <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键。
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 路由配置 path('uploads/', views.uploads_files, name='uploads'), setting.py必须配置 STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static') ] MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 运行后,打开上传的图片页面,这里我是在博客中插入的,可以根据自己的需求更改路径.支持多张图片同时上传呀。
在后台管理图片的时候,虽然可以查看图片,不过需要点击,很麻烦。
优化:
修改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 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了。