如何在Django Admin中添加自定义表单实现多规格商品动态创建?
Django Admin 多商品变体动态生成实现方案
第一步:配置Admin内联模型
在你项目对应app的admin.py文件中添加如下配置,即可实现同一个商品编辑页嵌套录入所有关联数据:
from django.contrib import admin from .models import Products, Attribute, Attribute_Value, Product_Option, Product_Combinations, Images # 变体图片内联组件 class ImagesInline(admin.TabularInline): model = Images extra = 1 # 商品组合内联组件 class ProductCombinationsInline(admin.TabularInline): model = Product_Combinations extra = 0 inlines = [ImagesInline] # 组合名称自动生成时可设为只读,需要手动调整可删除该配置 readonly_fields = ('combination',) # 商品属性选项内联组件 class ProductOptionInline(admin.TabularInline): model = Product_Option extra = 1 # 自定义商品管理后台 @admin.register(Products) class ProductsAdmin(admin.ModelAdmin): inlines = [ProductOptionInline, ProductCombinationsInline] # 引入自定义JS实现动态生成组合逻辑 class Media: js = ('admin/js/generate_combinations.js',) # 注册基础属性模型 admin.site.register(Attribute) admin.site.register(Attribute_Value)
第二步:添加动态生成组合的JS逻辑
在项目静态文件目录下新建admin/js/generate_combinations.js文件,实现选中属性后自动生成所有属性值的笛卡尔积组合:
django.jQuery(document).ready(function($) { // 插入生成组合按钮 $('.js-inline-admin-formset.inline-group').first().after('<button type="button" id="generate-combinations" class="button">生成所有商品组合</button>'); $('#generate-combinations').on('click', function() { let attributeValues = {}; // 收集所有选中的商品属性 $('.product_option-item select[name$="-options"]').each(function() { let attrId = $(this).val(); if (attrId) { // 异步拉取对应属性的所有可选值 $.get(`/admin/get-attribute-values/${attrId}/`, function(data) { attributeValues[attrId] = data.values; // 所有属性值拉取完成后生成组合 if (Object.keys(attributeValues).length === $('.product_option-item select[name$="-options"]').filter(function() {return $(this).val()}).length) { generateCombinations(attributeValues); } }); } }); }); function generateCombinations(attributeValues) { // 计算属性值的笛卡尔积 let combinations = cartesianProduct(Object.values(attributeValues)); let combinationFormset = $('#product_combinations-group .js-inline-admin-formset'); // 清空现有组合 combinationFormset.find('.dynamic-product_combinations').remove(); // 批量新增生成的组合 combinations.forEach(combo => { let comboText = combo.join(' | '); // 调用Django admin原生formset新增行方法 let newRow = combinationFormset.find('.add-row a').click()[0].closest('.dynamic-product_combinations'); $(newRow).find('input[name$="-combination"]').val(comboText); }); } // 笛卡尔积计算工具函数 function cartesianProduct(arrays) { return arrays.reduce((a, b) => a.flatMap(d => b.map(e => [d, e].flat()))); } });
第三步:添加属性值查询接口
在对应app的urls.py中新增接口路由,用于JS拉取指定属性的所有可选值:
from django.urls import path from .views import get_attribute_values urlpatterns = [ # 保留原有路由,新增以下配置 path('admin/get-attribute-values/<int:attr_id>/', get_attribute_values, name='get_attribute_values'), ]
在对应app的views.py中实现接口逻辑:
from django.http import JsonResponse from .models import Attribute_Value def get_attribute_values(request, attr_id): if not request.user.is_staff: return JsonResponse({'error': '无操作权限'}, status=403) values = list(Attribute_Value.objects.filter(attribute_id=attr_id).values_list('value', flat=True)) return JsonResponse({'values': values})
功能使用说明
- 新增商品时先添加需要用到的属性(比如尺寸、材质),点击「生成所有商品组合」按钮即可自动生成所有属性值的排列组合
- 每个生成的商品组合行可以单独设置价格、上传对应变体图片
- 可根据业务需求调整组合字段的只读权限,支持手动修改组合名称
内容的提问来源于stack exchange,提问作者SOURAV SARKAR
相关产品推荐
相关产品推荐

