django do not save thumbnails from imagekit - python

from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToFill
class Image(models.Model):
image = models.ImageField(upload_to='home/', blank=True)
thumbnail = ImageSpecField(source='image', processors=[ResizeToFill(50, 50)],format='JPEG', options={'quality':60})
when I uploading image. Everything OK with original image. But there is no thumbnail image.
I guess this problem is related with cache. Maybe I am wrong. Can't figure out what to do...
Please help.

In order to "enforce" file generation, your 'IMAGEKIT_DEFAULT_CACHEFILE_STRATEGYshould implementon_source_saved`.
One is provided but the package, and adding:
IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY = 'imagekit.cachefiles.strategies.Optimistic'
to your settings.py will enforce file generation on source save.
Now please pay attention: this will "only" work when using ImageSpecField and you might have an hard time using this strategy with templatetags or ImageSpec without handling correctly source groups
Another way is to write your custom CACHEFILE_STRATEGY``
Insome_app/strategy.py`
class CustomStrategy(object):
"""
A strategy that ensures file creation on save and existence
"""
def on_existence_required(self, file):
file.generate()
def on_content_required(self, file):
file.generate()
def on_source_saved(self, file):
file.generate()
Now, adding
IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY = 'your_app.strategy.CustomStrategy'
to your settings.py should work like a charm.

Related

How to pass an object between views in Django

I have the following model for my students to upload their tasks to an application that I am creating, but I have a problem, I need to pass an instance of the model between views, but since it is not serializable, I can not save it in a session attribute. Keep in mind that in one view I create the object without saving it in the database and in the other I perform operations with the object and finally I save it. Any idea how I can do this?
from gdstorage.storage import GoogleDriveStorage
gd_storage = GoogleDriveStorage()
class Homework(models.Model):
code = models.AutoField(primary_key=True)
student = models.ForeignKey('Student', on_delete=models.PROTECT)
title = models.CharField(unique=True, max_length=100)
attached_file = models.FileField(upload_to='files/homeworks/', validators=[validate_file_size], storage=gd_storage)
As #dirkgroten says, you can add an additional field to your model that is called status and by default assign it the value of temporary. In addition to this you can review the package code.
Finally to delete a file in Google Drive as a storage backend is very simple. Use the following
gd_storage.delete(name_file)
So change in the code of #dirkgroten
from django.core.files.storage import default_storage
#receiver (post_delete, sender=Homework)
def remove_file (sender, instance, **kwargs):
if instance.attached_file is not None:
gd_storage.delete(instance.attached_file.name)
The only way to keep "state" between views is to save to the database (or other permanent storage). That's what the session does for you.
If you can't serialise to save in the session, then you have no alternative but to save a temporary object to the database. You could mark it as temporary and add a timestamp. And in the next view mark it as committed. And if needed clean up once in a while, removing old temporary objects.
To remove the associated file with old temporary objects, you can add a signal handler for the post_delete signal:
from django.core.files.storage import default_storage
#receiver(post_delete, sender=Homework)
def remove_file(sender, instance, **kwargs)
path = instance.attached_file.name
if path:
default_storage.delete(path)

Convert blob to Django ImageField in python?

I read user image in BLOB file, but i want save it to image format in django model.
How can i convert this file to image file(.jpeg) and save it in django models.ImageField?
I use python 2.7 and django 1.9.
my model is:
class Staff(models.Model):
user = models.ForeignKey(User)
cn = models.CharField(max_length=100)
new_comer = models.NullBooleanField()
change_position = models.NullBooleanField()
change_manager = models.NullBooleanField()
acting = models.NullBooleanField()
expelled = models.NullBooleanField()
active = models.NullBooleanField()
avatar = models.ImageField(upload_to='/images/')
Please help me...
You need to try something like this.
import io
from django.core.files.base import File
# Set values of your model filed.
staff_instance = Staff()
staff_instance.user = user_instance
...
...
with io.BytesIO(blob_file) as stream:
django_file = File(stream)
staff_instance.avatar.save(some_file_name, django_file)
staff_instance.save()
I assume that blob is a byte array of the file.
To make it a file i need to convert it to a stream.
Thus I thought BytesIO would be a good choice.
You can directly save file to disk but if you want django to upload it to your upload_to directory, you need to use django.core.files.base.File class.
When you run django.core.files.base() method file will be saved to desired directory.
I guess you will use this for an data migration process, not in a view.
If this is the case than you could put this code at a django command.
Then you can use any django and project related resources.
Let me know if it helps.

CharField filenames into ImageFields in Django

I have a model:
class Photo(models.Model):
filename = models.CharField(max_length=240)
And a corresponding MySQL table, filled with filenames (copied from an existing table).
In the future I may want to upload new photos to the model via admin. Is it possible to evolve the current model into something with ImageFields and integrate my legacy data?
It is possible, assuming the current filename field in your model contains the full path to the actual file, you can add a new field (ImageField) to your model and migrate it using South, then write a script to update your data.
A skeleton example,
from django.core.files import File
# assuming your updated model looks like:
# class Photo(models.Model):
# filename = models.CharField(max_length=240)
# image = models.ImageField(max_length=240)
photos = Photo.objects.all()
for p in photos:
f = open(p.filename)
myimage = File(f)
p.image.save(image_name, myimage) # name, content
And then remove the old filename field via South. Take a look at Django's FileField first for more information, since ImageField essentially inherits all of the former's attribute and methods. (see https://docs.djangoproject.com/en/1.3/ref/models/fields/#django.db.models.FileField)

Django: persistent database-backed settings

I want to have some database stored settings for my Django app - just some key-value pairs. Does Django have a conventional way of doing this / something built in for it, or should I implement it myself?
class Setting(models.Model):
key = models.TextField()
value = models.TextField()
Of course, I'd want to be able to store any data type for keys and values. Perhaps I could use pickle to coerce them all into strings.
I've just been playing with the django-satchmo e-store application. Satchmo uses satchmo-livesettings or just livesettings to achieve this goal. In addition to that it is possible to change the settings using the admin interface.
The only problem is that I didn't find a tutorial on how to use livesettings. But if you browse the satchmo code, you'll see how it works.
Here is my example
from livesettings import config_register, StringValue, PositiveIntegerValue
SHOP_GROUP = ConfigurationGroup('SHOP', ('ShirtSale Shop Settings'), ordering=0)
CHARGE_PORTO = config_register(
BooleanValue(SHOP_GROUP,
'CHARGE_PORTO',
description = ('Porto Erheben?'),
help_text = ("Wird bei Bestellungen zusaetzlich ein Porto erhoben?"),
default = True))
I've included those lines in the config.py file. To execute this file it was necessary to:
import config
in the admin.py file (I'm wondering whether this is necessary)
In order to access the settings I've included the following to the urls.py file:
(r'^settings/', include('livesettings.urls')),

Django: manually create imagefield in model from existing file on server

This is killing me!
I'm using django-filebrowser, and I want to create a gallery app that leverages it's upload capabilities to manage images.
I have a Gallery model that allows the user to select or create a directory on the server, and upload files to that folder to appear in the gallery. I want to automatically trawl the directory that the user has uploaded images to and selected, and then automatically create Image instances for each image in the folder.
class Gallery(model.Models):
gallerydirectory = FileBrowserField(...)
title = ...
description ...
class Image(model.Models):
image_field = models.ImageField()
The problem is that FileBrowser represents images differently to Django, but I want to use DJango ImageFields as I can then use other apps (sorl thumbnails) on the template end.
I have all the data necessary for the file i.e. filename, path etc, I just can't get Django to create an instance of an ImageField, without actually uploading the image again. I simply want to populate it.
I have seen another thread here which suggests the following:
for image in filebrowser_image_objects_list:
f = File(open('path-to-file-on-server','r'))
i = Image()
i.image_field('filename.png',f.read())
but this is giving me a:
SuspiciousOperation error
Attempted access to '/filename.png' denied
which suggests that the path isn't being read correctly. I've printed the attributes of the File Object, and it is opening the correct image, it just isn't getting passed on to the ImageField
Help would be greately appreciated!
UPDATE
I've given up trying to get this work as it's just too messy. The problem I had above was that I had set the upload_field of the ImageField to '/' and it had gone unnoticed meaning that the file was being written to '/something.png'.
I've modified it so that the Image is now using a FileBrowserField as well instead of an ImageField.
I might be missing something, but this worked for me:
from a1.models import Model1
from django.core.files.images import ImageFile
m = Model1.objects.create()
m.f1 = ImageFile(open("1.png", "rb"))
m.save()
for the following model:
class Model1(models.Model):
f1 = models.ImageField()
This way it didn't work:
m.f1('1.png', File.read(open('1.png', 'r')))
It says:
TypeError: 'ImageFieldFile' object is not callable
Checked with Django 1.7, 1.11.
I'm marking this as answered, as this is the correct way to do this:
from django.core.files import File
image_model.image_field('path', File().read())
Programmatically saving image to Django ImageField
This works for me on Python3 with Django 2
from urllib.request import urlopen
from urllib.parse import urlparse
from io import BytesIO
from django.core.files.images import ImageFile
from .models import ModelWithImageField
# Solving for SSL Error
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
url = https://www.someurl.com/image.png?other_params_if_they_exist
image_file_name = urlparse(url).path.split('/')[-1]
image_file_content = BytesIO(urlopen(url).read())
ModelWithImageField().image_field.save(image_file_name, image_file_content)

Categories