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

如何在Django/Python中实现动态视图?寻求技术指导

Django动态视图实现指导(根据下拉菜单展示对应数据)

先看你代码里存在的几个核心问题:

  • 视图函数参数错误:Django视图的第一个参数必须是request,不是self,self是类方法专用的,函数视图不需要
  • 未获取前端传递的选择值:代码里的dropdown变量未定义,得从请求里提取前端传过来的参数
  • 代码极度冗余:一堆重复的elif逻辑完全可以用字典映射简化
  • 拼写错误:比如判断条件里的AplasticAneamia和导入的AplasticAnaemia不一致,Sicklecelldiseases和导入的Sicklecelldisease多了个s,会导致匹配失败
  • 返回格式不友好:直接返回HttpResponse(x)用户看不到友好展示,建议返回JSON或者渲染模板

第一步:修正并优化视图函数

先把导入的别名改清晰,再用字典映射类名到对应类,砍掉冗余代码:

from django.shortcuts import render
from django.http import HttpResponseBadRequest, JsonResponse
from Healthcare.Conditions.Blood.blood import (
    AcuteMyeloidLeukemia,
    ChronicMyeloidLeukemia,
    AcuteLymphoblasticLeukemia,
    NonHodkinLeukemia,
    HodgkinLymphoma,
    Myeloma,
    MyelodysplasticSyndrome,
    AplasticAnaemia,
    Autoimmunediseases,
    Sicklecelldisease,
    Thalassaemia
)

# 建立类名到类的映射字典,替代一堆elif
CONDITION_CLASSES = {
    'AcuteMyeloidLeukemia': AcuteMyeloidLeukemia,
    'ChronicMyeloidLeukemia': ChronicMyeloidLeukemia,
    'AcuteLymphoblasticLeukemia': AcuteLymphoblasticLeukemia,
    'NonHodkinLeukemia': NonHodkinLeukemia,
    'HodgkinLymphoma': HodgkinLymphoma,
    'Myeloma': Myeloma,
    'MyelodysplasticSyndrome': MyelodysplasticSyndrome,
    'AplasticAnaemia': AplasticAnaemia,
    'Autoimmunediseases': Autoimmunediseases,
    'Sicklecelldisease': Sicklecelldisease,
    'Thalassaemia': Thalassaemia
}

def symptoms_view(request):
    # 从GET请求里取下拉菜单的选择值,也可以用POST,看前端提交方式
    dropdown_value = request.GET.get('condition')
    
    if not dropdown_value:
        return HttpResponseBadRequest("请选择一个疾病类型")
    
    # 从映射字典里获取对应类
    ConditionClass = CONDITION_CLASSES.get(dropdown_value)
    if not ConditionClass:
        return HttpResponseBadRequest("无效的疾病类型")
    
    # 实例化并获取症状数据
    condition_instance = ConditionClass()
    symptoms = condition_instance.my_symptoms().values()
    
    # 返回JSON格式方便前端处理;如果要渲染模板就用render
    return JsonResponse(list(symptoms), safe=False)

第二步:前端实现下拉菜单交互

两种方案选适合你的:

方案1:表单提交(页面刷新)

创建模板symptoms.html,用表单提交选择值:

<!DOCTYPE html>
<html>
<head>
    <title>疾病症状查询</title>
</head>
<body>
    <form method="get" action="{% url 'symptoms_view' %}">
        <label for="condition">选择疾病类型:</label>
        <select name="condition" id="condition" onchange="this.form.submit()">
            <option value="">请选择</option>
            <option value="AcuteMyeloidLeukemia">急性髓系白血病</option>
            <option value="ChronicMyeloidLeukemia">慢性髓系白血病</option>
            <!-- 其他疾病选项依次添加 -->
        </select>
    </form>
    
    {% if symptoms %}
        <h3>症状列表:</h3>
        <ul>
            {% for symptom in symptoms %}
                <li>{{ symptom }}</li>
            {% endfor %}
        </ul>
    {% endif %}
</body>
</html>

对应的视图要改成渲染模板:

def symptoms_view(request):
    dropdown_value = request.GET.get('condition')
    symptoms = []
    if dropdown_value:
        ConditionClass = CONDITION_CLASSES.get(dropdown_value)
        if ConditionClass:
            condition_instance = ConditionClass()
            symptoms = list(condition_instance.my_symptoms().values())
    
    return render(request, 'symptoms.html', {'symptoms': symptoms})

方案2:AJAX异步加载(无刷新)

用JS监听下拉菜单变化,异步请求数据并展示:

<!DOCTYPE html>
<html>
<head>
    <title>疾病症状查询</title>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
</head>
<body>
    <label for="condition">选择疾病类型:</label>
    <select name="condition" id="condition">
        <option value="">请选择</option>
        <option value="AcuteMyeloidLeukemia">急性髓系白血病</option>
        <option value="ChronicMyeloidLeukemia">慢性髓系白血病</option>
        <!-- 其他疾病选项依次添加 -->
    </select>
    
    <div id="symptoms-container"></div>

    <script>
        $('#condition').change(function() {
            var condition = $(this).val();
            if (!condition) {
                $('#symptoms-container').empty();
                return;
            }
            
            $.ajax({
                url: "{% url 'symptoms_view' %}",
                data: { 'condition': condition },
                success: function(data) {
                    var html = '<h3>症状列表:</h3><ul>';
                    data.forEach(function(symptom) {
                        html += '<li>' + symptom + '</li>';
                    });
                    html += '</ul>';
                    $('#symptoms-container').html(html);
                },
                error: function() {
                    $('#symptoms-container').html('<p>加载失败,请重试</p>');
                }
            });
        });
    </script>
</body>
</html>

这种方案用之前返回JsonResponse的视图即可。


第三步:配置URL

在app的urls.py里添加路由:

from django.urls import path
from . import views

urlpatterns = [
    path('symptoms/', views.symptoms_view, name='symptoms_view'),
]

额外注意点

  • 确保my_symptoms()方法返回可迭代对象(比如字典),这样values()能正常取值
  • 生产环境建议对前端传入的参数做更严格校验,防止恶意请求
  • 可以从CONDITION_CLASSES的键动态生成下拉菜单选项,避免前端硬编码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 08:25:34