如何加载 ClearableFileInput / FileField 的初始值(在绑定表单之前)

ali*_*s51 6 django django-models django-forms

创建新对象(未绑定表单)时,如何为将在 ClearableFileInput 小部件中显示的 FileField 设置初始值?

我已尝试以下操作,但如果这是用户第一次创建对象,widget.value则不会返回实例:FeildFile

模型.py

class MyModel(models.Model):
    myfile=models.FileField()
Run Code Online (Sandbox Code Playgroud)

表格.py

class MyForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['myfile'].initial= 'myfile.pdf'

    class Meta:
        model = Issuer
        fields = ['myfile']
Run Code Online (Sandbox Code Playgroud)

这导致:

在此输入图像描述

同样,在 modelfield 中设置默认值也不起作用:

class MyModel(models.Model):
    myfile=models.FileField(default='myfile.pdf')
Run Code Online (Sandbox Code Playgroud)

小部件的初始值仍然是,但如果将其保留为空并保存,创建None文件对象。和绝对正确,并且该文件位于系统上,因为它是在表单保存后加载的。myfile.pdf settings.MEDIA_URLurls.py

我缺少的是在保存表单和创建对象之前将其显示为初始值。

这个答案表明您无法提供初始数据,但您可以提供带有url属性的初始值来伪造文件的外观。但尚不清楚你将如何做到这一点。

尝试以表单创建初始文件对象也会返回widget.value = None

class MyForm(forms.ModelForm):

    f_path = os.path.join(settings.BASE_DIR + settings.MEDIA_URL, 'myfile.pdf')

    f = open(f_path)
    myfile = File(f)

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['privacy_policy'].initial = self.myfile
Run Code Online (Sandbox Code Playgroud)

Seb*_*bin 2

你的最后一段代码非常接近。

您实际上是通过小部件告诉用户ClearableFileInput,如果用户在文件输入中没有输入任何内容,则初始值将是您的 pdf 文件。

但是,这只是为了显示,你必须在保存实例时实际放置逻辑!(FileField 不会为你做这件事)所以正确的做法是重写表单save()的方法,并且在创建的情况下,将实际文件作为值。像这样:

class MyForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        path = os.path.join(settings.MEDIA_ROOT, 'myfile.pdf')

        self.default_file = open(path)

        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['privacy_policy'].initial = File(self.default_file)
        self.fields['privacy_policy'].initial.url = default_storage.url('myfile.pdf')

    def save(self, commit=True):
        # Actually put the default file as a value if no input for creation
        if not self.instance.pk and not self.cleaned_data.get('privacy_policy'):
            self.instance.privacy_policy = self.default_file
            self.instance.privacy_policy._committed = True
        super().save(commit)
Run Code Online (Sandbox Code Playgroud)