Django 管理图片

    科技2022-07-12  151

    Django 管理图片

    图片的上传

    模型定义 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 注册到管理后台 admin.py @admin.register(Image) class ImageAdmin(admin.ModelAdmin): list_display = ('image',)

    这时,在后台就可以实现图片的上传了,显然不是我们想要的,我们是想在前端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') 运行后,打开上传的图片页面,这里我是在博客中插入的,可以根据自己的需求更改路径.

    支持多张图片同时上传呀。


    admin后台管理图片。

    在后台管理图片的时候,虽然可以查看图片,不过需要点击,很麻烦。

    优化:

    修改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了。

    Processed: 0.009, SQL: 8