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

如何在Django中从HTML表单向views.py传递模型类名称?

问题

我希望让用户能下载应用中展示的Django模型数据为Excel文件,但因为有多种模型类型,需要做通用化处理。目前我用以下HTML实现Plant模型的下载:

<form id="downloadfile" method="post" action="{% url 'download_file' filename='Irrelevant.xlsx'%}">
    {% csrf_token %}
    <input type="hidden" value="Plant" name="database" />
    <input type="submit" name="downloadfile"  class="btn btn-success" value="Download Plant">
</form>

对应的views.py代码:

# Define function to download excel file using template
from database.models import Plant

def download_file(request, filename=''):
    if 'downloadfile' in request.POST:
        db_name = request.POST.get('database')
        # 如何动态指定对应的模型?
        response = xlsx_generator(Plant, db_name) # db_name仅用于命名xlsx文件,是字符串
        return response

    else:
        # 处理其他POST请求的逻辑

现在我不想手动指定模型类,希望通过表单提交的database参数动态获取对应的模型类,然后传入xlsx_generator实现下载,请问能不能做到?具体怎么实现?

解决方案

完全可以实现,核心是通过模型名称到模型类的白名单映射来安全地动态获取模型,避免直接使用用户输入带来的安全风险,步骤如下:

1. 创建模型白名单映射

在views.py中,先导入所有需要支持下载的模型,然后创建一个字典,将模型名称(字符串)和对应的模型类关联起来:

from database.models import Plant, Animal, Product  # 导入所有需要支持的模型

# 模型白名单:仅允许列表内的模型被下载
MODEL_MAP = {
    'Plant': Plant,
    'Animal': Animal,
    'Product': Product,
}

2. 修改视图逻辑

在download_file函数中,从POST参数获取模型名称,然后从白名单字典中取出对应的模型类,再传入xlsx_generator:

def download_file(request, filename=''):
    if 'downloadfile' in request.POST:
        db_name = request.POST.get('database')
        # 从白名单中获取模型类,若不存在则返回错误或默认处理
        model_class = MODEL_MAP.get(db_name)
        if not model_class:
            # 处理无效模型名称的情况,比如返回400错误
            return HttpResponseBadRequest("Invalid model name")
        
        response = xlsx_generator(model_class, db_name)
        return response

    else:
        # 处理其他POST请求的逻辑

3. 扩展表单支持多模型

如果要支持其他模型的下载,只需要复制原表单,修改隐藏字段的value和按钮文字即可:

<!-- 下载Animal模型的表单 -->
<form id="download-animal" method="post" action="{% url 'download_file' filename='Irrelevant.xlsx'%}">
    {% csrf_token %}
    <input type="hidden" value="Animal" name="database" />
    <input type="submit" name="downloadfile"  class="btn btn-success" value="Download Animal">
</form>

<!-- 下载Product模型的表单 -->
<form id="download-product" method="post" action="{% url 'download_file' filename='Irrelevant.xlsx'%}">
    {% csrf_token %}
    <input type="hidden" value="Product" name="database" />
    <input type="submit" name="downloadfile"  class="btn btn-success" value="Download Product">
</form>

关键安全提示

不要直接使用django.apps.get_model()来解析用户输入的模型名称(比如get_model('database', db_name)),这种方式存在安全风险——恶意用户可以构造输入来访问你不想开放的模型。通过手动维护白名单字典,能严格控制允许下载的模型范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 00:15:30