models.py
from django.db
import models
class People(models.Model):
firstname = models.CharField(max_length = 100)
lastname = models.CharField(max_length = 100)
img = models.ImageField(upload_to = 'media/people')
In my particular case I'm uploading images for a gallery app. And having nice URL-friendly filenames would be a "feature". Having non-ASCII characters in an URL (even if allowed) can get quite messy, especially when server and browser speak different dialects, e.g. de_DE.utf8 and de_DE.latin1. , In order to avoid this error and non-ASCII characters in URLs I'd like to suggest a built-in (optional) conversion of the filename in the Image- and/or FileField class (or corresponding base class). , Many developers would be surprised if Django automatically altered the names of uploaded files, and it would be backwards incompatible, so we won't do that. , Locale settings are all ok. As I suspected it was a bug in the apache package of Ubuntu. I have reverted to the original code and uploaded (after Apache restart) a file containing a German umlaut. Everything went fine.
In order to avoid this error and non-ASCII characters in URLs I'd like to suggest a built-in (optional) conversion of the filename in the Image- and/or FileField class (or corresponding base class).
class MyImageField(ImageField):
def __init__(self, * args, ** kwargs):
super(MyImageField, self).__init__( * args, ** kwargs)
def clean(self, * args, ** kwargs):
data = super(MyImageField, self).clean( * args, ** kwargs)
filename = os.path.splitext(data.name)
data.name = unicode(data.name)
if len(filename[1]):
data.name += u '.' + slugify(filename[1])
return data
Another elegant solution woud be:
class MyImageField(ImageField):
def __init__(self, * args, ** kwargs):
super(MyImageField, self).__init__( * args, ** kwargs)
def clean(self, * args, ** kwargs):
data = super(MyImageField, self).clean( * args, ** kwargs)
data.name = data.name.encode('ascii', 'ignore')
return data
Should we offer this feature as an option? "Normalizing" file names is easy -- the snippet you pasted above shows how to do it -- but it's also a matter of taste. For instance, one could prefer:
data.name = unicodedata.normalize('NFKD', data.name).encode('ascii', 'ignore')
In order to rule out locale configuration issues, could you insert in a view :
import locale
locales = "Current locale: %s %s -- Default locale: %s %s" % (locale.getlocale() + locale.getdefaultlocale())
I expect:
Current locale: None None--Default locale: de_DE UTF8
This document tells you what you need to know if you’re writing applications that use data or templates that are encoded in something other than ASCII.,The LANG environment variable is responsible for setting the expected encoding on Unix platforms. Consult the documentation for your operating system and application server for the appropriate syntax and location to set this variable. See the How to use Django with Apache and mod_wsgi for examples.,Whenever you use strings with Django – e.g., in database lookups, template rendering or anywhere else – you have two choices for encoding those strings. You can use normal strings or bytestrings (starting with a ‘b’).,Most developers won’t need to worry about changing form encoding, but this is a useful feature for applications that talk to legacy systems whose encoding you cannot control.
>>> from urllib.parse
import quote
>>>
from django.utils.encoding
import iri_to_uri
>>>
quote('Paris & Orléans')
'Paris%20%26%20Orl%C3%A9ans' >>>
iri_to_uri('/favorites/François/%s' % quote('Paris & Orléans'))
'/favorites/Fran%C3%A7ois/Paris%20%26%20Orl%C3%A9ans'
>>> from django.utils.encoding
import uri_to_iri
>>>
uri_to_iri('/%E2%99%A5%E2%99%A5/?utf8=%E2%9C%93')
'/♥♥/?utf8=✓' >>>
uri_to_iri('%A9hello%3Fworld')
'%A9hello%3Fworld'
iri_to_uri(iri_to_uri(some_string)) == iri_to_uri(some_string) uri_to_iri(uri_to_iri(some_string)) == uri_to_iri(some_string)
from urllib.parse
import quote
from django.utils.encoding
import iri_to_uri
def get_absolute_url(self):
url = '/person/%s/?x=0&y=0' % quote(self.location)
return iri_to_uri(url)
from django.template
import Template
t2 = Template('This is a string template.')
import sys
sys.getfilesystemencoding()
Last modified: Jul 11, 2022, by MDN contributors
from django.db
import models
from django.urls
import reverse
class MyModelName(models.Model):
""
"A typical class defining a model, derived from the Model class."
""
# Fields
my_field_name = models.CharField(max_length = 20, help_text = 'Enter field documentation')
#…
# Metadata
class Meta:
ordering = ['-my_field_name']
# Methods
def get_absolute_url(self):
""
"Returns the URL to access a particular instance of MyModelName."
""
return reverse('model-detail-view', args = [str(self.id)])
def __str__(self):
""
"String for representing the MyModelName object (in Admin site etc.)."
""
return self.my_field_name
my_field_name = models.CharField(max_length = 20, help_text = 'Enter field documentation')
class CatalogConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
class Meta:
ordering = ['-my_field_name']
ordering = ['title', '-pubdate']
verbose_name = 'BetterName'