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

Django项目Choices字段HTML渲染异常问题求助

Django Choices字段渲染异常问题修复

问题说明

在Django项目中创建了包含3个带choices参数CharField的VehicleStatus模型,当前遇到渲染异常:页面上设置了三色编码的状态卡片,但搜索不同VIN时,卡片始终显示相同结果,无法根据后端选中的选项动态切换。

相关代码

models.py 模型定义

class VehicleStatus(models.Model):
    """
    车辆状态模型,包含事故记录、里程表欺诈、被盗记录
    """
    ACCIDENT_HISTORY = [
        ("NHA","无事故记录"),
        ("OIIA", "曾发生过一次事故"),
        ("CAD", "当前因事故受损"),
    ]

    ODOMETER_FRAUD = [
        ("NOF", "无里程表欺诈"),
        ("SOF",  "疑似里程表欺诈"),
    ]

    THEFT_INVOLVEMENT = [
        ("NHT", "无被盗记录"),
        ("OIT",  "曾被盗过一次"),
        ("STI", "疑似被盗"),
    ]

    vin_number = models.OneToOneField(Vin, on_delete=models.CASCADE, related_name='vehiclestatus', db_index=True, help_text="车辆识别码")
    accident_history = models.CharField(max_length=30, choices=ACCIDENT_HISTORY, default='NHA', help_text="车辆事故记录")
    odometer_fraud = models.CharField(max_length=30, choices=ODOMETER_FRAUD, default='NOF', help_text="是否疑似里程表欺诈")
    theft_involvement = models.CharField(max_length=30, choices=THEFT_INVOLVEMENT, default='NHT', help_text="是否涉及被盗")
    owner_history = models.IntegerField(help_text="前任车主数量", default=0)
    
    
    def __str__(self):
        return f"VIN {self.vin_number} 的状态信息"

    class Meta:
        verbose_name = "车辆状态"
        verbose_name_plural = "车辆状态"

视图函数

def search(request):
    # 从GET请求获取VIN码
    vin = request.GET.get('vin_number')
    vehicle = None
    specs = None
    inspections = []
    history_records = []
    vehicle_status = []
    message = None

    if vin:
        try:
            # 查询Vin模型
            vehicle = get_object_or_404(Vin, vin_number=vin)

            # 获取关联模型数据
            specs = getattr(vehicle, 'specs', None)
            inspections = vehicle.inspections.all()
            history_records = vehicle.history.all()
            # 错误:这里把history记录赋值给了vehicle_status,而非VehicleStatus对象
            vehicle_status = vehicle.history.all()

        except Vin.DoesNotExist:
            message = "未找到对应VIN码的车辆信息。"
        except Exception as e:
            message = f"查询出错:{str(e)}"
    else:
        message = "请输入VIN码进行查询。"

    # 渲染模板
    return render(request, 'autohistory/search.html', {
        'vehicle': vehicle,
        'specs': specs,
        'inspections': inspections,
        'history_records': history_records,
        'vehicle_status': vehicle_status,
        'message': message,
    })

HTML模板卡片代码

<!-- 事故记录卡片 -->
<div class="col-md-4 mb-3">
    <div class="card 
        {% if vehicle_status.accident_history == 'NHA' %}bg-success text-white
        {% elif vehicle_status.accident_history == 'OIIA' %}bg-warning text-dark
        {% else%}bg-danger text-white{% endif %}">
        <div class="card-header">
            <h5 class="card-title mb-0">
                <i class="fas fa-car-crash me-2"></i>
                事故记录
            </h5>
        </div>
        <div class="card-body">
            <p class="card-text">
                <strong>状态:</strong> {{ vehicle_status.get_accident_history_display }}
            </p>
            <p class="card-text small">
                {% if vehicle_status.accident_history == 'NHA' %}
                    该车辆无事故记录。
                {% elif vehicle_status.accident_history == 'OIIA' %}
                    该车辆曾发生过一次事故。
                {% else %}
                    该车辆当前因事故受损。
                {% endif %}
            </p>
        </div>
    </div>
</div>

问题根源

  1. 视图数据赋值错误:视图中vehicle_status = vehicle.history.all()是将车辆的历史记录(QuerySet列表)赋值给了vehicle_status,而非关联的VehicleStatus单例对象。模板中尝试直接访问vehicle_status.accident_history,列表对象没有该属性,导致逻辑判断失效,始终显示默认状态。
  2. OneToOne关联访问错误:VehicleStatus与Vin是OneToOne关系,related_name为vehiclestatus,正确的访问方式应该是vehicle.vehiclestatus。

修复方案

1. 修正视图函数中的数据赋值

将视图中vehicle_status的赋值语句修改为:

# 正确获取关联的VehicleStatus对象,若不存在则返回None
vehicle_status = getattr(vehicle, 'vehiclestatus', None)

2. 模板中增加空值判断

避免因vehicle_status为None导致模板报错,同时确保逻辑正确:

<!-- 事故记录卡片 -->
<div class="col-md-4 mb-3">
    {% if vehicle_status %}
    <div class="card 
        {% if vehicle_status.accident_history == 'NHA' %}bg-success text-white
        {% elif vehicle_status.accident_history == 'OIIA' %}bg-warning text-dark
        {% else%}bg-danger text-white{% endif %}">
        <div class="card-header">
            <h5 class="card-title mb-0">
                <i class="fas fa-car-crash me-2"></i>
                事故记录
            </h5>
        </div>
        <div class="card-body">
            <p class="card-text">
                <strong>状态:</strong> {{ vehicle_status.get_accident_history_display }}
            </p>
            <p class="card-text small">
                {% if vehicle_status.accident_history == 'NHA' %}
                    该车辆无事故记录。
                {% elif vehicle_status.accident_history == 'OIIA' %}
                    该车辆曾发生过一次事故。
                {% else %}
                    该车辆当前因事故受损。
                {% endif %}
            </p>
        </div>
    </div>
    {% else %}
    <div class="card bg-secondary text-white">
        <div class="card-header">
            <h5 class="card-title mb-0">
                <i class="fas fa-car-crash me-2"></i>
                事故记录
            </h5>
        </div>
        <div class="card-body">
            <p class="card-text">暂无车辆状态信息</p>
        </div>
    </div>
    {% endif %}
</div>

3. 可选:提前预取关联数据优化性能

在查询Vin时使用select_related预取VehicleStatus,减少数据库查询次数:

vehicle = get_object_or_404(Vin.objects.select_related('vehiclestatus'), vin_number=vin)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 23:10:59