Django Admin:自动补全选择后填充内联字段采购价格
在Django Admin内联表单中自动填充产品采购价格
要实现选择产品后自动填充对应采购价格的功能,需要结合前端JS监听选择事件,再通过后端接口获取价格数据,以下是具体实现步骤:
步骤1:编写自定义JavaScript文件
在项目静态文件目录(如static/admin/js/)下创建po_item_autofill.js,用于监听产品选择事件并完成价格填充:
document.addEventListener('DOMContentLoaded', function() { // 定义处理产品选择的逻辑 const handleProductSelect = function(e) { const selectedSku = e.params.data.id; // 定位当前内联行的采购价格输入框 const row = this.closest('.tabular.inline-related'); const priceInput = row.querySelector('input[name$="-purchasing_price"]'); if (!selectedSku || !priceInput) return; // 发送请求获取产品采购价格 fetch(`/admin/products/product/${selectedSku}/price/`) .then(response => response.json()) .then(data => { priceInput.value = data.purchasing_price ? data.purchasing_price.toFixed(2) : ''; }) .catch(error => console.error('获取价格失败:', error)); }; // 给初始加载的产品选择框绑定事件 document.querySelectorAll('.related-widget-wrapper select[name$="-product"]').forEach(selectElement => { $(selectElement).on('select2:select', handleProductSelect); }); // 监听动态添加的内联表单,给新生成的选择框绑定事件 document.querySelector('#content-main').addEventListener('DOMNodeInserted', function(e) { const newSelect = e.target.querySelector('.related-widget-wrapper select[name$="-product"]'); if (newSelect) { $(newSelect).on('select2:select', handleProductSelect); } }); });
步骤2:在Admin中引入自定义JS
修改PurchaseOrderAdmin类,添加Media配置引入上述JS文件:
@admin.register(PurchaseOrder) class PurchaseOrderAdmin(admin.ModelAdmin): class PoItemInline(admin.TabularInline): model = PoItem fields = ["product", "quantity", "purchasing_price"] extra = 1 autocomplete_fields = ["product"] form = PoItemInlineForm inlines = [PoItemInline] # 引入自定义JS class Media: js = ('admin/js/po_item_autofill.js',)
步骤3:创建获取产品价格的后端接口
在admin.py中添加一个视图函数,用于返回指定产品的采购价格:
from django.http import JsonResponse from django.contrib.admin.views.decorators import staff_member_required from .models import Product @staff_member_required def get_product_price(request, sku): try: product = Product.objects.get(sku=sku) return JsonResponse({ 'purchasing_price': product.purchasing_price }) except Product.DoesNotExist: return JsonResponse({'purchasing_price': None}, status=404)
然后在项目根目录的urls.py中添加该接口的路由:
from django.contrib import admin from django.urls import path from .admin import get_product_price urlpatterns = [ path('admin/', admin.site.urls), # 产品价格查询接口 path('admin/products/product/<str:sku>/price/', get_product_price, name='get_product_price'), ]
注意事项
- 由于
Product模型的主键是字符串类型的sku,路由中使用<str:sku>进行匹配 - JS中用
toFixed(2)将浮点数价格转为两位小数,与PoItem的DecimalField格式保持一致 - 开发环境需确保静态文件服务正常,生产环境需执行
collectstatic命令收集静态文件
内容的提问来源于stack exchange,提问作者rapsli
相关产品推荐
相关产品推荐

