Django FileField store Keras .h5 file - django

I am trying to store a trained Keras model within a Django model FileField. Since Keras is not pickleable, I used the .h5 file format (https://www.tensorflow.org/guide/keras/save_and_serialize) to store the keras model. So basically just:
kerasmodel.save('temp.h5')
dat = open('temp.h5', mode='r')
myFile = File(dat)
mymodel.content.save('test', myFile)
mymodel.content is the Django model FileField
This causes the error:
UnicodeDecodeError at /model/
'charmap' codec can't decode byte 0x90 in position 1928: character maps to "undefined"
I really don't care if Django can read this file or not, I just want to save it for later purposes. Since I can easily upload the file manually via the Django admin page to the model, it should be feasible.
Thanks in advance

Related

Do data conversion after Django model object is fetched

I want to save the python dictionary inside the Django model as JSON and I want to convert that JSON back into a python dictionary when that data is fetched.
I know I can do it inside view but I want to implement it in the model so it can return dictionary object when queried.
is there any signal or any post_fetch method that I can use to achieve it, I couldn't find anything googling it...
You might want to look into simply using the Python JSON package, unless you are using Postgres as your database - in which case JSONField is the way to go. The json package is explained here and you could use it in a model like so if I understand what you are saying:
import json
class MyModel(models.Model):
json_field = models.TextField() # or you can use JSONField if using Postgres
#property
def get_json_field_as_dictionary(self):
return json.loads(self.json_field)
def set_json_field(self, mydict):
self.json_field = json.dumps(mydict)
#classmethod
def get_json_from_dictionary(cls, mydict):
return json.dumps(mydict)
When you are saving to the database, you can use json.dumps(myDictionary) or convert the dictionary to JSON by calling MyModelObject.set_json_field(myDictionary) to convert a Python dictionary to JSON and then store it in the json_field of the model. To retrieve the JSON data as a dictionary, you simply call MyModel.objects.last().get_json_field_as_dictionary (or whatever you prefer to call it, json_dictionary perhaps so it would be MyModel.objects.last().json_dictionary) and it will return the value of that property as if it were an element in the model without having to do the conversion each time.
Or, if you are using Postgres as your backend, this is a lot easier with JSONField:
class MyModel(models.Model):
json_field = models.JSONField(null=True)
And to save:
myObject = myModel.objects.create(json_field=myDictionary)
If you clarify I can update my answer to explain better.
You may want to use JSONField. It allows storing data encoded as JSON and retrieve them as the corresponding Python data type, including dictionary.
JSONField only works on PostgreSQL with Django < 3.1, but works on any database with Django >= 3.1.

set default image to ImageField for existing objects in django

I have a model which has an ImageField.
class A(model.Model):
blah = CharField(max_length=10)
profile = ImageField(upload_to='uploads/', null=True, blank=True)
I want to set a default image for existing data, so I tried saving the file in shell like the following:
>>> myapp.models import A
>>> from django.core.files import File
>>> for a in A.objects.all():
>>> a.profile.save('default.jpg', File(open('/Users/myusername/Pictures/default.jpg', 'rb')))
I was quite happy, until I found out that in myprojectroot/media/uploads/ there are as many defaultblablah.jpg files as the number of A objects.
I'd like to know if there's any way to set the same image file with all objects as you do with update() method.
Could someone shed some lights on it?
Thank you in advance.
Yes, you can store a file default.jpg in the uploads/ directory, and then update the objects with:
A.objects.filter(profile=None).update(profile='uploads/default.jpg')
I would also advise to make the field non-nullable, and use as default an value:
class A(model.Model):
blah = CharField(max_length=10)
profile = ImageField(
upload_to='uploads/',
default='uploads/default.jpg',
blank=True
)
Behind the curtains an ImageField is a varchar field in the database, that stores a path to the image you use. The Django ImageField has extra logic such that it presents it as a FieldFile [Django-doc] with some logic, but it is stored in the database as a string.
The reason why it will generate multiple images, is because you can later decide to edit one of the images. If that is the case, all of the other images would see these edits. So if the filename "clashes", it will make copies to prevent this. If you however make use of a default image, the idea is to not modify that image. Therefore it might also be a good idea to mark the file as readonly.

How can I set my very own JSON key label in Django REST API framework?

I'm trying to use REST API framework in Django and I noticed that the JSON format for it always takes the particular model's field name as the key. eg: A field called image in my model stores images in the database. When viewed in JSON format, it's seen as : {"image": "apple.png"}
I want to change the image to my own personalized label. How can I do this?
You can create a serializer with your custom label name and then use custom attribute to instruct drf to use image field data.
Something like
custom_label = serializers.TextField(source="image")

Django how ImageField and BinaryField works for image

So i wanted to ask how does these 2 fields works.
As my friend told me that his ios will sent byte format image to me, does it matter if i use imageField instead of BinaryField ?
I did try adding a Binaryfield into my User models but when testing it out on django admin and also django rest framework api, it doenst work
In django admin : the binaryfield did not appear in it
In django rest framework : got an error that says editable is false for binary field. Setting the binaryfield editable=True also doesnt work.
The documentation about Binaryfield in django is also not much.
Can anyone please explain to me how does these 2 field work ? does sending byte format to the imagefield work ?
The ImageField takes care of pictures. Otherwise, ImageField and FileField are the same. Both store the path to a file of the pysical volume.
And both do not meet the requirements.
The database requires a BinaryField:
models.BinaryField (blank = true, null = true, editable = true)
So far so good. With editable = True, the field should appear in the admin interface. But to see the picture, it has to be transformed again before
encoded = b64encode (model.image) .decode ('ascii')
and e.g. poured into a form.
render_to_string ('lib / forms / imageform.html', {"image": encoded}, request).
The form element in my case looks like this:
<form id = "{{form.fid}}" class = "form-horizontal data-form" enctype = "multipart / form-data" method = "post">
<img src = "data: image / png; base64, {{image}}">
</ Form>
ImageField or FileField is what you should use to save images. Both of these fields just save the file_path (Ex: /static/user_images/smith.jpg) to the physical image stored on the server.
For more detail read this FileField and ImageField
BinaryField not used to save images. For more detail
Note : that you never store a physical file to a Database. That is you don't use BinaryField for images.

Handling files in Django

I'm using ImageMagick and the binding wand to generate thumbnails for uploaded images in Django. I can generate the thumbnail fine, but I'm uncertain about how to go about passing the image object from ImageMagick back into the Django model. So I have a simplified model as below:
from wand import Image
class Attachment(models.Model):
attachment = models.FileField(upload_to="some_path")
thumbnail = models.ImageField(upload_to="other_path")
def generate_thumb(self):
with Image(file=self.attachment) as wand:
thumb = wand.resize(width=50, height=50)
thumb.save(file=self.thumbnail)
This generates an error at the last line of ValueError: The 'thumbnail' attribute has no file associated with it. Is there a simple way to get a file object out of wand and into django without too much silliness?
Thanks.
Disclaimer: I am the creator of Wand you are trying to use.
First of all, ImageField requires PIL. It means you don’t need Wand, because you probably already installed an another image library. However I’ll answer to your question without any big changes.
It seems that self.thumbnail was not initialized yet at the moment, so you have to create a new File or ImageFile first:
import io
def generate_thumb(self):
buffer = io.BytesIO()
with Image(file=self.attachment) as wand:
wand.resize(width=50, height=50)
wand.save(file=buffer)
buffer.seek(0)
self.thumbnail = ImageFile(buffer)
Plus, from wand import Image will raise ImportError. It should be changed:
from wand.image import Image
If the goal is easy thumbnails in your django app try: https://github.com/sorl/sorl-thumbnail
Its pretty popular and active.