Django : customizing FileField value while editing a model
You need to override the ClearableFileInput that is currently used, to change the way it's displayed.
Here is the code of the new ShortNameFileInput
which inherit from the default ClearableFileInput
with just a change on the 19th line to only show the file name:
from django.forms.widgets import ClearableFileInputimport os# missing importsfrom django.utils.safestring import mark_safefrom cgi import escapefrom django.utils.encoding import force_unicodeclass ShortNameClarableFileInput(ClearableFileInput): def render(self, name, value, attrs=None): substitutions = { 'initial_text': self.initial_text, 'input_text': self.input_text, 'clear_template': '', 'clear_checkbox_label': self.clear_checkbox_label, } template = u'%(input)s' substitutions['input'] = super(ClearableFileInput, self).render(name, value, attrs) if value and hasattr(value, "url"): template = self.template_with_initial substitutions['initial'] = (u'<a href="%s">%s</a>' % (escape(value.url), escape(force_unicode(os.path.basename(value.url))))) # I just changed this line if not self.is_required: checkbox_name = self.clear_checkbox_name(name) checkbox_id = self.clear_checkbox_id(checkbox_name) substitutions['clear_checkbox_name'] = conditional_escape(checkbox_name) substitutions['clear_checkbox_id'] = conditional_escape(checkbox_id) substitutions['clear'] = CheckboxInput().render(checkbox_name, False, attrs={'id': checkbox_id}) substitutions['clear_template'] = self.template_with_clear % substitutions return mark_safe(template % substitutions)
To use it in your form, you'll have to manually set the widget you want to use :
class DemoVar_addform(ModelForm): ... class Meta: model = DemoVar_model widgets = { 'Welcome_sound': ShortNameClarableFileInput, }
That should do the trick.
If you want an easier way and avoid to rewrite the render logic of the widget, you can do a little hack.
from os import pathfrom django import formsclass FormatString(str): def format(self, *args, **kwargs): arguments = list(args) arguments[1] = path.basename(arguments[1]) return super(FormatString, self).format(*arguments, **kwargs) class ClearableFileInput(forms.ClearableFileInput): url_markup_template = FormatString('<a href="{0}">{1}</a>')
And then manually set the widget for the field.
class DemoVar_addform(ModelForm): class Meta: model = DemoVar_model widgets = { 'Welcome_sound': ClearableFileInput, }
Django 1.10.x or older version
The easiest way is to override the template_substitution_values
in default ClearableFileInput
django widget that will be used later in rendering the form. This is a much cleaner approach that does not result in any unnecessary code duplication.
from os import pathfrom django.forms.widgets import ClearableFileInputfrom django.utils.html import conditional_escapeclass CustomClearableFileInput(ClearableFileInput): def get_template_substitution_values(self, value): """ Return value-related substitutions. """ return { 'initial': conditional_escape(path.basename(value.name)), 'initial_url': conditional_escape(value.url), }
then use the widget in forms.py as follow:
class DemoVar_addform(ModelForm): Welcome_sound = forms.FileField(widget=CustomClearableFileInput) ... class Meta: model = DemoVar_model ...
Django 1.11.x or later versions
Check ImageField / FileField Django form Currently unable to trim the path to filename.