Django: настройка значения FileField при редактировании модели
у меня есть модель, с FileField
. Когда я редактирую эту модель в представлении, я хочу изменить "текущее" значение FileField
который отображается в форме представления. Позвольте мне объяснить.
models.py:
class DemoVar_model(models.Model):
...
Welcome_sound=models.FileField(upload_to='files/%Y/%m/%d')
forms.py:
class DemoVar_addform(ModelForm):
...
class Meta:
model = DemoVar_model
views.py:
soundform = DemoVar_addform(instance=ivrobj)
....
return render_to_response(template,{'soundform':soundform}, ....)
теперь я хочу отредактировать эту модель в моем представлении. Когда я смотрю в браузере, я вижу, что форма отображается как
Welcome sound: Currently: welcome_files/2011/04/27/15_35_58_ojCompany.wav.mp3
Change : <Choose File button>
Я хочу чтобы изменить это значение "в настоящее время", которое описывает весь путь к файлу по мере его выхода на моем сервере. Я хочу обрезать эту строку только до имени файла без пути. Как мне это сделать?
4 ответов
вам нужно переопределить ClearableFileInput, который в настоящее время используется, чтобы изменить способ его отображения.
вот код нового ShortNameFileInput
которые наследуются от значения по умолчанию ClearableFileInput
только с изменением на 19-й строке, чтобы показать только имя файла:
from django.forms.widgets import ClearableFileInput
import os
# missing imports
from django.utils.safestring import mark_safe
from cgi import escape
from django.utils.encoding import force_unicode
class 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)
чтобы использовать его в своей форме, вам придется вручную установить виджет, который вы хотите использовать:
class DemoVar_addform(ModelForm):
...
class Meta:
model = DemoVar_model
widgets = {
'Welcome_sound': ShortNameClarableFileInput,
}
это должно сделать трюк.
Если вы хотите более простой способ и избежать перезаписи логики рендеринга виджета, вы можете немного взломать.
from os import path
from django import forms
class 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>')
и затем вручную установите виджет для поля.
class DemoVar_addform(ModelForm):
class Meta:
model = DemoVar_model
widgets = {
'Welcome_sound': ClearableFileInput,
}
Джанго 1.10.x или более старая версия
самый простой способ-переопределить template_substitution_values
по умолчанию ClearableFileInput
Django виджет, который будет использоваться позже в рендеринге формы. Это намного более чистый подход, который не приводит к ненужному дублированию кода.
from os import path
from django.forms.widgets import ClearableFileInput
from django.utils.html import conditional_escape
class 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),
}
затем используйте виджет вforms.py как следовать:
class DemoVar_addform(ModelForm):
Welcome_sound = forms.FileField(widget=CustomClearableFileInput)
...
class Meta:
model = DemoVar_model
...
Джанго 1.11.x или более поздние версии
Регистрация ImageField / FileField форма Django в настоящее время не удается обрезать путь к имени файла.
один из способов сделать это-написать пользовательский виджет формы и переопределить метод рендеринга.