【问题标题】:Django Admin - Upload multiple images to multiple model objects in a single uploadDjango Admin - 一次上传多个图像到多个模型对象
【发布时间】:2019-06-18 08:10:53
【问题描述】:

我的模型在数据库中有近 15 万个条目。
如今,在编辑特定条目时,可以分别为每个条目上传一张图片。

我们需要上传接近 4k 个图像文件,每个条目一个,我想通过允许上传多个文件来实现,其中图像文件名将与模型的名称属性匹配。

基本模型示例:

class Entry(models.Model):
    name = models.CharField(unique=True, max_length=200, db_index=True)
    image = models.ImageField(null=True, blank=True)

有没有办法创建一个视图来支持多个文件的一个上传按钮(其中每个文件代表数据库中模型的不同条目),并在上传处理程序/存储后端处理其余部分?

【问题讨论】:

标签: django django-admin django-uploads


【解决方案1】:

默认情况下一次更新数千条记录具有挑战性。

一个问题是数据库端的性能。我能想到的最好的就是 使用update 并覆盖一些方法。 假设您已经在某个目录中保存了图像。

from django.db.models import fields
from django.db.models import F
from django.db.models.expressions import Value , CombinedExpression
from django.db.models import QuerySet

class TextValue(Value):
    def as_sql(self, compiler, connection):
        connection.ops.check_expression_support(self)
        return '%s', [self.value]

class Expr(F):
    ADD = '||'  # standard concat row value + value in PostgreSQL

    #overwrite method to support text
    def _combine(self, other, connector, reversed):
        if not hasattr(other, 'resolve_expression'):
            other = TextValue(other, output_field=fields.CharField())

        return CombinedExpression(self, connector, other)


class Entry(models.Model):
    name = models.CharField(unique=True, max_length=200, db_index=True)
    image = models.ImageField(upload_to= 'media/' , null=True, blank=True , default='default.png')

现在有了这个代码,你可以批量更新

entries= Entry.objects.all() 
entries.update(**{'image': Expr('name') + '.png'})

这样做最好的部分是性能。这是唯一执行的查询

{'sql': 'UPDATE "entry" SET "image" = ("entry"."name" || \'.png\')', 'time': '0.024'}]

更新

与管理员做同样的事情并为每个条目保存一个模型实例。

from django.contrib import  admin
from django import forms


class EntryForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(EntryForm, self).__init__(*args, **kwargs)
        self.fields['image'].widget.attrs.update(
            {'multiple': True, 'accept': 'image/jpg,image/png,image/gif', })


class EntryAdmin(admin.ModelAdmin):
    form = EntryForm

    def save_model(self, request, obj, form, change):
        files = request.FILES.getlist('image')

        # if image exist
        if files:
            for image_field in files:
                try:
                    instance = Entry.objects.get(name=image_field.name[:-4])
                    instance.image = image_field
                    instance.save()
                except Entry.DoesNotExist:
                    pass
        else:
            return super().save_model(request, obj, form, change)



admin.site.register(Entry , EntryAdmin)

你可以混合这两个部分来获得击球性能

【讨论】:

  • 感谢 Naqib 的详细回答,但恐怕它没有解决问题的 Django Admin 部分。手头的问题不是如何为多个数据库行设置不同的值,而是如何使用 Django Admin 框架来完成。在 Django Admin 中,Django UI 与幕后的模型相结合,并且有允许操作这些对象 (MVC) 的视图。操作通常通过 Django 表单进行,但我找不到一种方法来使用单个表单来允许上传多个图像并将每个图像分配到数据库中的不同行。
猜你喜欢
  • 2018-12-11
  • 2010-10-29
  • 2021-11-05
  • 1970-01-01
  • 2021-04-07
  • 1970-01-01
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多