使用 ModelChoiceField 在 Django 表单中显示 pk 以外的字段

Displaying fields other than pk in a Django Form with a ModelChoiceField

我正在构建一个网站,用户可以在其中上传文件并将上传内容附加到他们事先创建的项目中。上传是使用 django 表单完成的,用户可以在其中指定标题、评论等。还有一个下拉列表,用户可以从中选择他创建的现有项目(项目列表取决于用户) 截至目前,下拉列表仅显示(自动生成的)项目 ID,它是模型项目的 pk。

我希望下拉列表显示项目名称而不是项目 ID,这对用户来说意义不大。

我已经试过了

to_field_name='name' 

但这没有用

我也试过了

Project.objects.filter(user=user).values_list('name')

or

Project.objects.filter(user=user).values('name')

最后两个选项在 {'projectname} 中显示了项目名称,但是当我 select 它们并提交表单时出现错误 "Select a valid choice. That choice is not one of the available choices."

这是我的代码:

models.py

class Upload(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    upload_date = models.DateTimeField(default=timezone.now)
    comments = models.CharField(max_length=10000, null=True)
    title = models.CharField(max_length=10000, null=True)
    project = models.CharField(max_length=99, default='--None--')

forms.py

class UploadForm(ModelForm):
    project = ModelChoiceField(label='Select Project', queryset=Project.objects.all(), to_field_name='name',
                               empty_label='--Select Project--')

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super(UploadForm, self).__init__(*args, **kwargs)
        if user is not None:
            self.fields['project'].queryset = Project.objects.filter(user=user)

    class Meta:
        model = Upload
        fields = ['title', 'project', 'upload_date', 'comments']

根据文档

The str() method of the model will be called to generate string representations of the objects for use in the field’s choices. To provide customized representations, subclass ModelChoiceField and override label_from_instance. This method will receive a model object and should return a string suitable for representing it.

https://docs.djangoproject.com/en/2.2/ref/forms/fields/#modelchoicefield

所以您应该为 Project 模型定义 __str__() method,例如

def __str__(self):
    return self.name