遭受FilePathField的“陈旧”选择

时间:2015-06-05 00:56:14

标签: django

我有一个显示目录内容的表单中的FilePathField 预期。但是,如果我在目录中添加或删除文件 更改未在表单中更新。

以下是来自:

来自django导入表格

class MyForm(forms.Form):
    the_file = forms.FilePathField(path='c:/temp')

和相应的观点:

from django.shortcuts import render_to_response, get_object_or_404
from forms import MyForm

def test(request):
    form = MyForm()
    return render_to_response('test.html', {'form' : form}) 

2 个答案:

答案 0 :(得分:0)

我注意到选择菜单中没有反映新文件夹后,今天遇到了这个问题。

当django启动时({python)解析FilePathField类时)Form初始化一次。然后将目录的内容存储在字段本身中,然后在程序的生命周期内保留。

这种行为是出乎意料的(至少是我)并没有明确记录。

下面的讨论意味着只有在显式Form类中使用FilePathField时才会发生这种情况,而不是在动态生成的ModelForm中。

参见:https://groups.google.com/forum/#!searchin/django-developers/FilePathField $ 20refresh / django-developers / mHK-9N75swM / 3k13dC5HVQoJ

相关错误:https://code.djangoproject.com/ticket/16429

在论坛上都没有引起太多关注,所以我怀疑它属于边缘区域,可能是因为它的修复可能会很混乱。

更新我实施了一个愚蠢的解决方法。每当您需要新表单时,都会调用__init__方法。在该方法中,使用与原始参数相同的参数初始化新的FilePathField。新的将有一个目录条目的新副本,并用新副本替换陈旧的选择。

为了避免滥用文件系统,请在缓存中保留这些选项的副本5秒钟。

from django import forms
from django.core.cache import cache

class MyAwesomeForm(forms.Form): 
    _filepath_kw = dict(path='/some/dir',
                        label="Path to source images.",
                        recursive=True, allow_files=False,
                        allow_folders=True)

    my_field = forms.FilePathField(**_filepath_kw)

    def __init__(self, **kwargs):
        key = 'filepath-cache-key'
        choices = cache.get(key)
        if not choices:
            field = forms.FilePathField(**self._filepath_kw)
            choices = field.choices
            cache.set(key, choices, 5)

        super().__init__(**kwargs)
        self.base_fields['source'].choices = choices

如果你的目录是 huge ,那么在缓存中存储数以万计的文件记录可能非常慢,可能是个坏主意。

如果文件系统在POST后立即更改,这将导致验证问题,但是,这可能是一件好事。

我今天下午将此更改推送到应用程序,所以如果我发现可怕的意外后果,我会更新这个答案。

答案 1 :(得分:0)

如果您不想使用缓存,但对每次调用此表单都会读取实际文件或文件夹感到满意的话,则可以使用以下解决方案:

class ApproveUpdateForm(forms.Form):
    #to ensure that the file list is updated each time ApproveUpdateForm is called
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.fields['app'] = forms.FilePathField(path=settings.EXAMPLE_EXCH_DIR, match='.*\.tar.gz',
                                             label=_("Application"))
        self.fields['app'].widget.attrs['class'] = 'form-control'