You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django:使用CreateView时在模板Select中仅显示对象指定属性(不改__str__)

自定义Django表单下拉框显示内容(不修改模型__str__方法)

问题场景

现有以下Django模型、视图及模板代码:

模型代码

class Usuario(models.Model):
    login = models.CharField(max_length=200)
    senha = models.CharField(max_length=200)
    meta = models.ManyToManyField('meta', through='Usuario_meta')

    def __str__(self):
        return f'id: {self.id} - login: {self.login} - senha: {self.senha}'

class Meta(models.Model):
    tipo = models.CharField(max_length=200)

    def __str__(self):
        return f'id: {self.id} - senha: {self.tipo}'

class Usuario_meta(models.Model):
    usuario = models.ForeignKey(Usuario,on_delete=models.CASCADE)
    meta = models.ForeignKey(Meta,on_delete=models.CASCADE)
    data = models.DateField()
    valor = models.IntegerField()

    def __str__(self):
        return f'Meta do usuário: {self.usuario} - meta:{self.meta} - data:{self.data} - valor: {self.valor}'

视图代码

class UsuarioMetaCreate(CreateView):
    model = Usuario_meta
    template_name = 'lancamento_meta_cadastro.html'
    fields = '__all__'

原模板代码

<form action="" method="post">
    {% csrf_token %}
    {{form}}
    <input type="submit" value="Submit" />
</form>

默认渲染后,usuario下拉框会调用Usuario模型的__str__方法显示完整字符串,但需求是仅显示login属性,且不能修改模型的__str__方法。尝试直接在模板中使用{{form.usuario.login}}无效果,需要可行方案。


解决方案

方法一:自定义表单类,重写label_from_instance

通过自定义ModelForm,为usuario字段指定ModelChoiceField并修改选项的显示逻辑,无需修改模型代码。

  1. 创建自定义表单(可在forms.py或views.py中定义):
from django import forms
from .models import Usuario_meta, Usuario

class UsuarioMetaForm(forms.ModelForm):
    usuario = forms.ModelChoiceField(
        queryset=Usuario.objects.all(),
        label='Usuário',
        # 重写选项显示逻辑,仅返回login字段
        label_from_instance=lambda obj: obj.login
    )

    class Meta:
        model = Usuario_meta
        fields = '__all__'
  1. 修改视图,指定使用自定义表单:
class UsuarioMetaCreate(CreateView):
    model = Usuario_meta
    template_name = 'lancamento_meta_cadastro.html'
    form_class = UsuarioMetaForm  # 替换为自定义表单类
  1. 模板仍使用原代码即可:
<form action="" method="post">
    {% csrf_token %}
    {{form}}
    <input type="submit" value="Submit" />
</form>

这种方式简洁高效,适合需要全局复用该表单的场景。


方法二:模板中手动渲染下拉框

若不想修改后端代码,可直接在模板中手动生成select元素,自定义选项显示内容。

修改后的模板代码:

<form action="" method="post">
    {% csrf_token %}
    <!-- 手动渲染usuario下拉框 -->
    <div>
        <label for="{{ form.usuario.id_for_label }}">Usuário:</label>
        <select id="{{ form.usuario.id_for_label }}" name="{{ form.usuario.name }}">
            {% for usuario in form.usuario.field.queryset %}
                <option value="{{ usuario.id }}" {% if usuario.id == form.usuario.value %}selected{% endif %}>
                    {{ usuario.login }}
                </option>
            {% endfor %}
        </select>
        <!-- 显示字段错误信息 -->
        {% if form.usuario.errors %}
            <div style="color: red;">{{ form.usuario.errors }}</div>
        {% endif %}
    </div>
    <!-- 渲染其余字段 -->
    <div>{{ form.meta.label_tag }} {{ form.meta }}</div>
    <div>{{ form.data.label_tag }} {{ form.data }}</div>
    <div>{{ form.valor.label_tag }} {{ form.valor }}</div>
    <input type="submit" value="Submit" />
</form>

这种方式灵活性高,仅需修改模板代码,适合单个页面的定制需求。


内容的提问来源于stack exchange,提问作者Matheus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 16:23:17