I'm a Django newbie, I hope you could help me.
I'm developing a photo gallery app, and right now I'm trying to implement EXIF data extraction. It's working pretty well with pictures that were uploaded before the model migration, however, whenever I try to upload a new picture, I get this error:
ValidationError at /admin/picture/picture/add/
['“2021:11:12 15:26:56” value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format.']
It looks like DateTimeField and EXIF's CreateDate use a different format: DateTimeField uses YYYY-MM-DD HH:MM, while EXIF's CreateDate uses YYYY:MM:DD HH:MM.
Is there any way to solve this?
Here's my picture model:
from exiffield.fields import ExifField
from exiffield.getters import exifgetter
class Picture(models.Model):
image = models.ImageField(upload_to=get_image_upload_path)
[...]
# METADATA
created_on = models.DateTimeField(blank=True, editable=False, null=True)
width = models.PositiveIntegerField(editable=False, blank=True, null=True)
height = models.PositiveIntegerField(editable=False, blank=True, null=True)
size = models.CharField(max_length=20, editable=False, blank=True, null=True)
camera_make = models.CharField(max_length=20, editable=False, blank=True, null=True)
camera_model = models.CharField(max_length=20, editable=False, blank=True, null=True)
lens = models.CharField(max_length=20, editable=False, blank=True, null=True)
iso = models.PositiveIntegerField(editable=False, blank=True, null=True)
shutter_speed = models.CharField(max_length=20, editable=False, blank=True, null=True)
latitude = models.CharField(max_length=20, editable=False, blank=True, null=True)
longitude = models.CharField(max_length=20, editable=False, blank=True, null=True)
exif = ExifField(
source='image',
denormalized_fields={
'created_on': exifgetter('CreateDate'),
'width': exifgetter('ImageWidth'),
'height': exifgetter('ImageHeight'),
'size': exifgetter('FileSize'),
'camera_make': exifgetter('Make'),
'camera_model': exifgetter('Model'),
'lens': exifgetter('LensInfo'),
'iso': exifgetter('ISO'),
'shutter_speed': exifgetter('ShutterSpeed'),
'latitude': exifgetter('GPSLatitude'),
'longitude': exifgetter('GPSLongitude'),
},
)
And here's the full error:
Traceback (most recent call last):
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/exiffield/fields.py", line 186, in denormalize_exif
value = extract_from_exif(exif_data)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/exiffield/getters.py", line 30, in inner
return exif[field]['val']
KeyError: 'Make'
Could not execute `exifgetter("Model")` to extract value for `Picture.camera_model`
Traceback (most recent call last):
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/exiffield/fields.py", line 186, in denormalize_exif
value = extract_from_exif(exif_data)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/exiffield/getters.py", line 30, in inner
return exif[field]['val']
KeyError: 'Model'
Could not execute `exifgetter("LensInfo")` to extract value for `Picture.lens`
Traceback (most recent call last):
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/exiffield/fields.py", line 186, in denormalize_exif
value = extract_from_exif(exif_data)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/exiffield/getters.py", line 30, in inner
return exif[field]['val']
KeyError: 'LensInfo'
Could not execute `exifgetter("ISO")` to extract value for `Picture.iso`
Traceback (most recent call last):
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/exiffield/fields.py", line 186, in denormalize_exif
value = extract_from_exif(exif_data)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/exiffield/getters.py", line 30, in inner
return exif[field]['val']
KeyError: 'ISO'
Could not execute `exifgetter("ShutterSpeed")` to extract value for `Picture.shutter_speed`
Traceback (most recent call last):
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/exiffield/fields.py", line 186, in denormalize_exif
value = extract_from_exif(exif_data)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/exiffield/getters.py", line 30, in inner
return exif[field]['val']
KeyError: 'ShutterSpeed'
Could not execute `exifgetter("GPSLatitude")` to extract value for `Picture.latitude`
Traceback (most recent call last):
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/exiffield/fields.py", line 186, in denormalize_exif
value = extract_from_exif(exif_data)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/exiffield/getters.py", line 30, in inner
return exif[field]['val']
KeyError: 'GPSLatitude'
Could not execute `exifgetter("GPSLongitude")` to extract value for `Picture.longitude`
Traceback (most recent call last):
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/exiffield/fields.py", line 186, in denormalize_exif
value = extract_from_exif(exif_data)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/exiffield/getters.py", line 30, in inner
return exif[field]['val']
KeyError: 'GPSLongitude'
Internal Server Error: /admin/picture/picture/add/
Traceback (most recent call last):
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/contrib/admin/options.py", line 683, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/utils/decorators.py", line 133, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/views/decorators/cache.py", line 62, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/contrib/admin/sites.py", line 242, in inner
return view(request, *args, **kwargs)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1885, in add_view
return self.changeform_view(request, None, form_url, extra_context)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/utils/decorators.py", line 46, in _wrapper
return bound_method(*args, **kwargs)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/utils/decorators.py", line 133, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1745, in changeform_view
return self._changeform_view(request, object_id, form_url, extra_context)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1797, in _changeform_view
self.save_model(request, new_object, form, not add)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1220, in save_model
obj.save()
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/picture/models.py", line 85, in save
super(Picture, self).save(*args, **kwargs)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/base.py", line 806, in save
self.save_base(
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/base.py", line 857, in save_base
updated = self._save_table(
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/base.py", line 1000, in _save_table
results = self._do_insert(
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/base.py", line 1041, in _do_insert
return manager._insert(
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/query.py", line 1434, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1620, in execute_sql
for sql, params in self.as_sql():
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1547, in as_sql
value_rows = [
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1548, in <listcomp>
[
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1549, in <listcomp>
self.prepare_value(field, self.pre_save_val(field, obj))
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1487, in prepare_value
value = field.get_db_prep_save(value, connection=self.connection)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/fields/__init__.py", line 910, in get_db_prep_save
return self.get_db_prep_value(value, connection=connection, prepared=False)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/fields/__init__.py", line 1546, in get_db_prep_value
value = self.get_prep_value(value)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/fields/__init__.py", line 1524, in get_prep_value
value = super().get_prep_value(value)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/fields/__init__.py", line 1403, in get_prep_value
return self.to_python(value)
File "/Users/temporaryadmin/DHTA_Projects/Group_Project/venv/lib/python3.8/site-packages/django/db/models/fields/__init__.py", line 1506, in to_python
raise exceptions.ValidationError(
django.core.exceptions.ValidationError: ['"2021:11:12 15:26:56" value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format.']
Thanks a lot in advance!
I managed to solve the issue, as exiffield has a specific getter for this:
Get when the file was created as datetime
So what I did is the following: