Problema
El sistema corre para servir a un público que tiene dentro de su lenguaje muchos caracteres no ASCII. Por defecto y con un sistema ideado para soportar UTF-8 Django no da problemas. El problema se presenta cuando se debe subir archivos que contienen caracteres no ASCII, ya que dependiendo de las configuraciones del servidor Django podría dar errores 500 cada vez que se intenta subir un archivo con tilde o ñ o cualquier carácter no ASCII.
Escenario
El sistema se basa en Django y utiliza los siguientes programas para servir en producción, Nginx, Supervisor, Gunicorn y Postgres.
Ver la siguiente guía para si se desea crear una ambiente semejante al descrito en este excelente enlace Setting up Django with Nginx, Gunicorn, virtualenv, supervisor and PostgreSQL
Solución
Revisar en /etc/locale.gen cuales locales tiene disponible el sistema. ej. es_CR.UTF-8 UTF-8
Si desea incluir algún otro locale puede descomentarlo en el archivo y ejecutar.
$ update-locale
Ejecutando en una shell el siguiente comando podemos verificar cuales locales están corriendo en este momento
$ locale
Es recomendable ejecutar locale con el usuario usado por supervisor para correr nuestras aplicaciones.
Otra verificación importante está explicada en la documentación para entornos de prueba. Files Django doc
El punto que soluciona el problema es indicarle a Gunicorn que corra con el locale adecuado, esto se hace según la documentación pasando un parámetro de entorno como --env LANG=es_CR.UTF-8 de forma que la línea quede como la siguiente.
exec ../bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--user=$USER --group=$GROUP \
--bind=unix:$SOCKFILE \
--log-level=info \
--env LANG=es_CR.UTF-8
--log-file=-
Recomendación: Aunque teóricamente basta con reiniciar el servicio con supervisor.
$ supervisorctl restart miapp
No nos funcionó hasta que reiniciamos supervisor y nginx.
$ service supervisor restart
$ service nginx restart