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

如何在Django表单中展示SQL查询结果并实现图书复选框多选提交

Django书店图书选购表单实现方案

需求说明

  • 从MSSQL数据库读取Books表所有图书数据渲染到表单
  • 每条图书记录前增加复选框供用户勾选选购
  • 图书信息字段使用CharField,设置disabled=True禁止编辑,采用Textarea作为输入小部件
  • 表单提交后提取所有选中图书的UID列表,用于后续订单入库等业务逻辑
  • 现有环境:Django对接SQL Server 2019正常,数据库连接配置无误

代码修改步骤

1. 重写forms.py

原有单ModelForm仅支持单条图书数据,需要调整为支持多条数据的表单集,同时新增复选框字段,配置只读规则:

from django.forms import ModelForm, modelformset_factory
from django import forms
from .models import Books


class BookRowForm(forms.ModelForm):
    # 新增选购复选框,非必填
    selected = forms.BooleanField(required=False, label="选购")
    class Meta:
        model = Books
        fields = ['selected', 'uid', 'bookname', 'author', 'category', 'qty', 'price']
        # 统一给所有图书信息字段设置Textarea小部件、禁用编辑、非必填
        widgets = {
            'uid': forms.Textarea(attrs={'disabled': True, 'rows':1}),
            'bookname': forms.Textarea(attrs={'disabled': True, 'rows':1}),
            'author': forms.Textarea(attrs={'disabled': True, 'rows':1}),
            'category': forms.Textarea(attrs={'disabled': True, 'rows':1}),
            'qty': forms.Textarea(attrs={'disabled': True, 'rows':1}),
            'price': forms.Textarea(attrs={'disabled': True, 'rows':1}),
        }

# 生成图书表单集,不额外生成空行,默认拉取所有图书数据
BookFormSet = modelformset_factory(Books, form=BookRowForm, extra=0)

2. 修正views.py业务逻辑

原有视图未处理GET请求初始化、表单集绑定、选中UID提取逻辑,调整后代码如下:

from django.shortcuts import render
from .models import Books
from .forms import BookFormSet


def Homepage(request):
    selected_uids = []
    if request.method == 'POST':
        # 绑定提交的POST数据到表单集
        formset = BookFormSet(request.POST, queryset=Books.objects.all())
        if formset.is_valid():
            # 遍历表单提取选中的图书UID
            for book_form in formset:
                if book_form.cleaned_data.get('selected'):
                    selected_uids.append(book_form.cleaned_data.get('uid'))
            # 此处可直接使用selected_uids写入orders订单表
            # 例:Order.objects.bulk_create([Order(book_id=uid) for uid in selected_uids])
    else:
        # GET请求初始化空表单集,绑定所有图书数据
        formset = BookFormSet(queryset=Books.objects.all())
    
    return render(request, 'Homepage.html', {
        'formset': formset,
        'selected_uids': selected_uids # 可选:传选中结果到模板做提示
    })

3. 调整Homepage.html模板

原有模板未适配表单集渲染规则,需要补充表单集必须的管理字段,调整渲染顺序把复选框放在每条图书最前面:

<html>
<head>
    <title>HomePage</title>
    <link rel="icon" type="image/x-icon" href="/MainWinIcon.ico">
</head>
<body style="text-align:center;vertical-align:middle;background-color:rgb(62,245,226);">
    <h1>Welcome to HomePage Select the Books you want and Press Submit</h1>
    
    <form method="post">
        {% csrf_token %}
        <!-- 表单集必须渲染管理字段,否则会触发校验错误 -->
        {{ formset.management_form }}
        <fieldset style="max-width: 800px; margin: 0 auto;">
            {% for book_form in formset %}
            <div style="background: #fff; border: 1px solid #333; margin: 10px 0; padding: 15px; text-align: left;">
                <!-- 最前面渲染选购复选框 -->
                <div style="padding-bottom: 10px; border-bottom: 1px solid #eee;">
                    {{ book_form.selected }} <label>选购此书</label>
                </div>
                <!-- 渲染隐藏字段 -->
                {% for hidden in book_form.hidden_fields %}
                    {{ hidden }}
                {% endfor %}
                <!-- 渲染只读图书信息字段 -->
                {% for field in book_form.visible_fields %}
                    {% if field.name != 'selected' %}
                    <div style="margin: 8px 0;">
                        <label style="display: inline-block; width: 80px;">{{ field.label }}:</label>
                        {{ field }}
                    </div>
                    {% endif %}
                {% endfor %}
            </div>
            {% endfor %}
            <input type="submit" value="Submit" style="padding: 8px 20px; margin: 20px 0;">
        </fieldset>
    </form>

    <h2 style="text-align:center;vertical-align:middle;background-color:grey">Books List</h2>
</body>
</html>

注意事项

  • 表单集必须渲染{{ formset.management_form }},否则Django会抛出校验异常
  • 字段设置disabled=True后,前端无法修改内容,Django会自动用绑定的模型实例值填充清洗后的数据,无需额外添加隐藏传值字段
  • 提取到的selected_uids是纯UID列表,可以直接对接后续订单创建、库存扣减等业务逻辑
  • 现有SQL Server 2019连接配置可直接复用,Django ORM会自动完成数据查询,不需要手写原生SQL

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 00:54:20