Джанго. Заменить сохранение для модели
Перед сохранением модели я перерисую картинку. Но как я могу проверить, добавлено ли новое изображение или просто обновлено описание, поэтому я могу пропустить масштабирование при каждом сохранении модели?
class Model(model.Model):
image=models.ImageField(upload_to='folder')
thumb=models.ImageField(upload_to='folder')
description=models.CharField()
def save(self, *args, **kwargs):
if self.image:
small=rescale_image(self.image,width=100,height=100)
self.image_small=SimpleUploadedFile(name,small_pic)
super(Model, self).save(*args, **kwargs)
Я хочу перемасштабировать только при обновлении нового изображения или обновлении изображения, но не при обновлении описания.
Ответы
Ответ 1
Некоторые мысли:
class Model(model.Model):
_image=models.ImageField(upload_to='folder')
thumb=models.ImageField(upload_to='folder')
description=models.CharField()
def set_image(self, val):
self._image = val
self._image_changed = True
# Or put whole logic in here
small = rescale_image(self.image,width=100,height=100)
self.image_small=SimpleUploadedFile(name,small_pic)
def get_image(self):
return self._image
image = property(get_image, set_image)
# this is not needed if small_image is created at set_image
def save(self, *args, **kwargs):
if getattr(self, '_image_changed', True):
small=rescale_image(self.image,width=100,height=100)
self.image_small=SimpleUploadedFile(name,small_pic)
super(Model, self).save(*args, **kwargs)
Не уверен, что он будет хорошо играть со всеми инструментами псевдо-авто django (пример: ModelForm, contrib.admin и т.д.).
Ответ 2
Проверьте поле модели pk. Если это None, то это новый объект.
class Model(model.Model):
image=models.ImageField(upload_to='folder')
thumb=models.ImageField(upload_to='folder')
description=models.CharField()
def save(self, *args, **kwargs):
if 'form' in kwargs:
form=kwargs['form']
else:
form=None
if self.pk is None and form is not None and 'image' in form.changed_data:
small=rescale_image(self.image,width=100,height=100)
self.image_small=SimpleUploadedFile(name,small_pic)
super(Model, self).save(*args, **kwargs)
Изменить: я добавил чек для "изображения" в form.changed_data. Предполагается, что вы используете сайт администратора для обновления ваших изображений. Вам также придется переопределить метод save_model по умолчанию, как указано ниже.
class ModelAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.save(form=form)
Ответ 3
Вы можете указать дополнительный аргумент для подтверждения публикации нового изображения.
Что-то вроде:
def save(self, new_image=False, *args, **kwargs):
if new_image:
small=rescale_image(self.image,width=100,height=100)
self.image_small=SimpleUploadedFile(name,small_pic)
super(Model, self).save(*args, **kwargs)
или переменная запроса передачи
def save(self, request=False, *args, **kwargs):
if request and request.FILES.get('image',False):
small=rescale_image(self.image,width=100,height=100)
self.image_small=SimpleUploadedFile(name,small_pic)
super(Model, self).save(*args, **kwargs)
Я думаю, что они не нарушат ваше спасение при простом вызове.
Вы можете поместить это в свой admin.py, чтобы эта работа с административным сайтом тоже (для второго из вышеперечисленных решений):
class ModelAdmin(admin.ModelAdmin):
....
def save_model(self, request, obj, form, change):
instance = form.save(commit=False)
instance.save(request=request)
return instance
Ответ 4
То, что я сделал для достижения цели, было сделать это.
# I added an extra_command argument that defaults to blank
def save(self, extra_command="", *args, **kwargs):
и ниже метода save() это.
# override the save method to create an image thumbnail
if self.image and extra_command != "skip creating photo thumbnail":
# your logic here
поэтому, когда я редактирую некоторые поля, но не редактируя изображение, я помещаю это.
Model.save("skip creating photo thumbnail")
вы можете заменить "skip creating photo thumbnail"
на "im just editing the description"
или более формальный текст.
Надеюсь, что это поможет!
Ответ 5
Запросить базу данных для существующей записи с тем же PK. Сравните размеры файлов и контрольные суммы новых и существующих изображений, чтобы узнать, совпадают ли они.
Ответ 6
В новой версии это выглядит так:
def validate(self, attrs):
has_unknown_fields = set(self.initial_data) - set(self.fields.keys())
if has_unknown_fields:
raise serializers.ValidationError("Do not send extra fields")
return attrs
Ответ 7
Я нашел еще один простой способ хранения данных в базе данных
models.py
class LinkModel(models.Model):
link = models.CharField(max_length=500)
shortLink = models.CharField(max_length=30,unique=True)
В базе данных у меня только 2 переменные
views.py
class HomeView(TemplateView):
def post(self,request, *args, **kwargs):
form = LinkForm(request.POST)
if form.is_valid():
text = form.cleaned_data['link'] # text for link
dbobj = LinkModel()
dbobj.link = text
self.no = self.gen.generateShortLink() # no for shortLink
dbobj.shortLink = str(self.no)
dbobj.save() # Saving from views.py
В этом я создал экземпляр модели только в views.py и поместил/сохранил данные в 2 переменные только из представлений.