如何用Ajax和Django实现医疗应用的动态多选药品及金额求和功能?
嘿,这个需求在医疗类应用里太实用了,我来一步步给你拆解怎么用 Ajax + Django 实现,保证清晰易懂:
实现步骤拆解
1. Django 后端准备
首先得把后端的数据接口搭好,让前端能拿到药品列表,核心交互逻辑虽然在前端,但后端得先把数据通道打通。
1.1 定义药品模型
先在你的 Django app 里创建药品模型,包含名称和价格两个核心字段:
# models.py from django.db import models class Drug(models.Model): name = models.CharField(max_length=100, verbose_name="药品名称") price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="单价") def __str__(self): return self.name
记得迁移数据库:python manage.py makemigrations 和 python manage.py migrate,之后可以通过后台或者脚本添加一些测试药品数据。
1.2 编写视图返回药品数据
写一个简单的视图函数,把所有药品数据以 JSON 格式返回,供前端 Ajax 获取:
# views.py from django.http import JsonResponse from .models import Drug def drug_list(request): drugs = Drug.objects.all().values('id', 'name', 'price') return JsonResponse({'drugs': list(drugs)})
1.3 配置 URL
在 app 的 urls.py 里添加对应路由:
# urls.py from django.urls import path from . import views urlpatterns = [ path('drugs/', views.drug_list, name='drug_list'), # 其他项目路由... ]
2. 前端页面实现
前端需要完成三个核心功能:加载药品列表、处理选中/取消事件、展示已选药品并计算总和。
2.1 HTML 结构
先搭好页面的基本框架,分成三个功能区域:
<!-- templates/your_template.html --> <!DOCTYPE html> <html> <head> <title>药品选择</title> <!-- 加个简单样式提升体验 --> <style> .container { display: flex; gap: 30px; padding: 20px; max-width: 1200px; margin: 0 auto; } .drug-selection { flex: 1; padding: 20px; border-right: 1px solid #eee; } .selected-drugs { flex: 1; padding: 20px; } .drug-item { margin-bottom: 10px; padding: 8px 12px; background: #f8f9fa; border-radius: 4px; display: flex; justify-content: space-between; align-items: center; } .remove-btn { background: #dc3545; color: white; border: none; border-radius: 3px; padding: 4px 8px; cursor: pointer; } .checkbox-item { margin-bottom: 8px; } </style> </head> <body> <div class="container"> <div class="drug-selection"> <h3>药品列表</h3> <div id="drug-list"></div> <!-- Ajax动态加载药品checkbox --> </div> <div class="selected-drugs"> <h3>已选药品</h3> <div id="selected-panel"> <p style="color: #6c757d;">暂无选中药品</p> </div> <div style="margin-top: 25px;"> <label>总金额:</label> <input type="text" id="total-amount" readonly value="0.00" style="padding: 6px; width: 100px;"> </div> </div> </div> <!-- 引入jQuery简化Ajax和DOM操作 --> <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> {% csrf_token %} <!-- Django CSRF令牌,必须加 --> <script> // 核心交互逻辑写在这里 </script> </body> </html>
2.2 JavaScript 交互逻辑
把下面的代码放到上面的 script 标签里,实现完整交互:
$(document).ready(function() { // 配置CSRF令牌,解决Django Ajax跨域问题 var csrftoken = $("[name=csrfmiddlewaretoken]").val(); $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } }); // 1. 从后端加载药品列表 $.ajax({ url: "{% url 'drug_list' %}", // Django模板标签生成路由 type: "GET", success: function(response) { var drugList = $('#drug-list'); drugList.empty(); $.each(response.drugs, function(index, drug) { var checkboxItem = $('<div>').addClass('checkbox-item') .append($('<input>').attr({ type: 'checkbox', class: 'drug-checkbox', 'data-id': drug.id, 'data-name': drug.name, 'data-price': drug.price })) .append(' ' + drug.name + ' - ¥' + drug.price); drugList.append(checkboxItem); }); } }); // 2. 监听药品选中/取消事件 $(document).on('change', '.drug-checkbox', function() { var isChecked = $(this).is(':checked'); var drugId = $(this).data('id'); var drugName = $(this).data('name'); var drugPrice = parseFloat($(this).data('price')); if (isChecked) { // 移除默认提示文字 if ($('#selected-panel p').length > 0) { $('#selected-panel').empty(); } // 添加到已选面板 var drugItem = $('<div>').addClass('drug-item').attr('data-id', drugId) .append('<span>' + drugName + ' - ¥' + drugPrice.toFixed(2) + '</span>') .append($('<button>').addClass('remove-btn').text('移除').click(function() { // 移除时同步取消checkbox选中,并重新计算总和 $('.drug-checkbox[data-id="' + drugId + '"]').prop('checked', false); $(this).parent().remove(); // 如果面板空了,重新显示提示文字 if ($('#selected-panel .drug-item').length === 0) { $('#selected-panel').append('<p style="color: #6c757d;">暂无选中药品</p>'); } calculateTotal(); })); $('#selected-panel').append(drugItem); } else { // 从已选面板移除 $('#selected-panel .drug-item[data-id="' + drugId + '"]').remove(); // 如果面板空了,重新显示提示文字 if ($('#selected-panel .drug-item').length === 0) { $('#selected-panel').append('<p style="color: #6c757d;">暂无选中药品</p>'); } } // 实时计算总金额 calculateTotal(); }); // 3. 计算总金额的工具函数 function calculateTotal() { var total = 0; // 遍历所有选中的checkbox累加价格 $('.drug-checkbox:checked').each(function() { total += parseFloat($(this).data('price')); }); // 更新总金额输入框,保留两位小数 $('#total-amount').val(total.toFixed(2)); } });
3. 额外优化建议
- 数据精度:金额计算用
toFixed(2)强制保留两位小数,避免浮点数精度误差。 - 用户体验:可以给选中的药品项添加高亮样式,或者在移除按钮上添加hover效果。
- 批量操作:如果需要的话,还可以添加“全选”“清空已选”按钮,进一步提升效率。
这样一套流程下来,就能完美实现你要的功能:多选药品、在独立面板展示已选项、实时自动计算总金额~
内容的提问来源于stack exchange,提问作者Daniel Kilanko
相关产品推荐
相关产品推荐

