Django: настройка значения FileField при редактировании модели - PullRequest
9 голосов
/ 28 апреля 2011

У меня есть модель с 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 ]

11 голосов
/ 28 апреля 2011

Вам нужно переопределить 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,
        }                    

Это должно сработать.

9 голосов
/ 18 декабря 2013

Если вы хотите более простой способ и не переписываете логику рендеринга виджета, вы можете сделать небольшой взлом.

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,
        }   
3 голосов
/ 30 мая 2017

Django 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

    ...

Django 1.11.x или более поздних версий


Проверка Форма Django ImageField / FileField В настоящее время не может обрезать путь к имени файла .

1 голос
/ 28 апреля 2011

Один из способов сделать это - написать собственный виджет формы и переопределить метод рендеринга.

...