Subclass Django Admin Form
Last Updated: 2121Z 06OCT20 (Created: 1846Z 05OCT20)

When I was planning to add image uploads to my blog, I remembered that jpg images created by smartphones include a significant amount of metadata including but not limited to time, location, course, speed, and altitude; all of which are components of Essential Elements of Friendly Information (EEFI) and should not be disclosed willy-nilly.

Therefore, I needed to figure a solution for automatically stripping the metadata from jpgs as I upload them to my blog site.

User Stories

As an author I want metadata automatically stripped from uploaded images so that I do not dox myself by sharing geotags.

Solution

models.py

class PostImage(models.Model):
    image = models.ImageField(upload_to='uploads/%Y/%m/%d/')

admin.py

import subprocess
from io import BytesIO

from django import forms
from django.contrib import admin
from django.core.files import File

from . import models

def _strip_metadata(fp):
    # copied from [1]

    args = ['exiftool', '-All=', '-']
    proc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    out, err = proc.communicate(input=fp.read())
    return BytesIO(out)

class PostImageAdminForm(forms.ModelForm):
    def clean_image(self):
        # image (above) maps to the image field on PostImage. copied from [1]

        f_orig = self.cleaned_data['image']
        fn = f_orig.name
        sanitized_image = _strip_metadata(f_orig)
        f_new = File(sanitized_image)
        f_new.name = fn
        return f_new

class PostImageAdmin(admin.ModelAdmin):
    list_display = ('pk', 'title', 'created')
    form = PostImageAdminForm

admin.site.register(models.PostImage, PostImageAdmin)

Results

The image below has been uploaded and the metadata has been stripped from the file.

Strip Meta Data Test Image

Figure 1: Strip Meta Data Test Image