【问题标题】:Django : customizing FileField value while editing a modelDjango:在编辑模型时自定义 FileField 值
【发布时间】:2011-08-14 05:22:35
【问题描述】:

我有一个模型,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>

我想更改这个“当前”值,它描述了文件在我的服务器上退出时的整个路径。我想将此字符串修剪为没有路径的文件名。我该如何做到这一点?

【问题讨论】:

    标签: python django file-upload django-forms django-file-upload


    【解决方案1】:

    您需要覆盖当前使用的 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,
            }                    
    

    这应该可以解决问题。

    【讨论】:

    • 为什么我不能从 FileInput 而不是 ClearableFileInput 派生?
    【解决方案2】:

    如果您想要一种更简单的方法并避免重写小部件的呈现逻辑,您可以做一些小技巧。

    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】:

    Django 1.10.x 或更早版本


    最简单的方法是覆盖默认的ClearableFileInput django 小部件中的template_substitution_values,该小部件稍后将用于呈现表单。这是一种更简洁的方法,不会导致任何不必要的代码重复。

    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 或更高版本


    检查ImageField / FileField Django form Currently unable to trim the path to filename

    【讨论】:

    【解决方案4】:

    一种方法是编写一个自定义表单小部件并覆盖渲染方法。

    【讨论】:

      猜你喜欢
      • 2020-06-29
      • 1970-01-01
      • 2017-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-06
      • 1970-01-01
      • 2016-01-09
      相关资源
      最近更新 更多