Обновлять тысячи записей одновременно сложно по умолчанию.
Одной из проблем является производительность на стороне базы данных. лучшее, что я мог придумать,
используя 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)
вы можете смешать эти две части, чтобы получить производительность теста