Django 3 ModelChoiceField保持为空

Django 3 ModelChoiceField保持为空,django,Django,我有两个字段的表单。第二个字段应填充现有项目的名称,但渲染时保持为空且不显示下拉列表 class UploadRawForm(forms.ModelForm): orig_file = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True})) project = forms.ModelChoiceField(queryset=Project.objects.all(), required=

我有两个字段的表单。第二个字段应填充现有项目的名称,但渲染时保持为空且不显示下拉列表

class UploadRawForm(forms.ModelForm):
    orig_file = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
    project = forms.ModelChoiceField(queryset=Project.objects.all(), required=True)
    class Meta:
        model = RawFile
        fields = ['orig_file', 'project']
模板:

{% extends 'base.html' %}

{% block title %}File upload{% endblock %}

{% block content %} 
    <h1> {{ name }} </h1>
    <form method="POST" id="upload-form" class="upload-form" enctype="multipart/form-data" novalidate>
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="save btn btn-default">Upload</button>
    </form>

    {% if form.errors %}
        {% for field in form %}
            {% for error in field.errors %}
                <p> {{ error }} </p>
            {% endfor %}
        {% endfor %}
    {% endif %}

{% endblock %}
models.py

class RawFile(models.Model):
    # use the custom storage class fo the FileField
    orig_file = models.FileField(upload_to = media_file_name, 
                                 storage = public_storage, 
                                 max_length = 1000)
    md5sum = models.CharField(max_length = 36, 
                              default = timezone.now, 
                              unique = True)
    created = models.DateField(default=timezone.now)
    project = models.ForeignKey(Project, on_delete=models.CASCADE, null=False)

    def save(self, *args, **kwargs):
        print('Saving new raw file.', self.md5sum)
        if not self.pk:  # file is new
            md5 = hashlib.md5()
            for chunk in self.orig_file.chunks():
                md5.update(chunk)
            self.md5sum = md5.hexdigest()
        if not self.id:
            self.created = timezone.now()
        print('Saving new raw file.', self.md5sum)

        try:
            super(RawFile, self).save(*args, **kwargs) 
        except IntegrityError as e:
            pass

    def __str__(self):
        return basename(self.orig_file.name)

    @property
    def abs_path(self): 
        return f'{PUBLIC_MEDIA_ROOT}/{self.orig_file}'

    @property
    def filename(self):
        return basename(self.abs_path)

    @property
    def path(self):
        return dirname(self.abs_path)

    @property
    def rawtools_status(self):
        path = dirname(self.abs_path)
        if isfile('QcDataTable.csv'):
            return 'Done'
        elif isfile(join(path, 'rawtools.txt')):
            return 'Running'
        return 'New file'

    @property    
    def href(self):
        return os.path.dirname('/'+self.orig_file.name)

    def link(self):
        print(self.href)
        return mark_safe(r'<a href="{}">Output</a>'.format(self.href))

    link.short_description = 'Browse'
可用的项目将显示在HTML代码中,但:

原始文件:

项目: --------- 冠状病毒 LSARP

上传
如果要重新定义所有生成的字段,为什么要使用ModelForm

下面是我要做的:

# forms.py
class UploadRawForm(forms.ModelForm):
    orig_file = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))

    class Meta:
        model = RawFile
        fields = ['orig_file', 'project']

您的模型和模板似乎正常

您需要修复表单:

class UploadRawForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['project'].queryset = Project.objects.all()

    class Meta:
        model = RawFile
        fields = ['orig_file', 'project']
        widgets = {
            'orig_file': forms.ClearableFileInput(attrs={'multiple': True}),
        }
关于
orig_文件
字段:您只需更改其小部件,因此只需向
Meta.widgets
dict添加一个条目

关于
项目
字段:无需完全覆盖已提供给您的内容。只需在表单初始化期间修改查询集。在您的情况下,您甚至可能不需要修改queryset,因为默认设置已经是
Project.objects.all()
。因此,您的表单可以是:

class UploadRawForm(forms.ModelForm):
    class Meta:
        model = RawFile
        fields = ['orig_file', 'project']
        widgets = {
            'orig_file': forms.ClearableFileInput(attrs={'multiple': True}),
        }

模板包含materialize.css,这导致下拉列表不显示。我补充说

  <script>
    $(document).ready(function() {
    $('select').material_select(); 
    });
  </script>

$(文档).ready(函数(){
$('select')。材料选择();
});

导入materialize文件的正后方。

如果要使用以前的数据或初始数据填充表单,则在
views.py
文件中启动表单时,应执行以下操作:

form = JournalForm(initial={'tank': 123})
tank = forms.IntegerField(widget=forms.HiddenInput(), initial=123) 
或者,在
forms.py
文件中设置值,如下所示:

form = JournalForm(initial={'tank': 123})
tank = forms.IntegerField(widget=forms.HiddenInput(), initial=123) 

小部件属性应该可以工作。像这样:

project = forms.ModelChoiceField(
    queryset= Project.objects.all(),
    widget=forms.Select(attrs={'class': 'form-control', 'required': True}), empty_label='')

仅供确认,您的
项目
模型是否至少包含一个数据?是的…………需要添加更多字符。该代码看起来正常。也许问题出在模型或视图中,我也添加了该代码。我在管理面板中得到了一个包含所有可用项目的下拉列表。
tank = forms.IntegerField(widget=forms.HiddenInput(), initial=123) 
project = forms.ModelChoiceField(
    queryset= Project.objects.all(),
    widget=forms.Select(attrs={'class': 'form-control', 'required': True}), empty_label='')