Django中选择CPU时自动填充采购价格的实现方法
Django表单选择CPU自动填充采购价格实现方案
需要实现的功能:在添加PC的表单中,当用户选择CPU(处理器)下拉选项时,自动将该CPU对应的采购价格填充到表单的「Стоимость покупки(采购成本)」输入框中。
现有模型与表单代码
PCModel模型
class PCModel(models.Model): PC_name = models.CharField('Названние компьютера', max_length=60) # 计算机名称 CPU = models.ForeignKey('CPUModel', verbose_name='Процессор', on_delete=models.SET_NULL, blank=True, null=True) GPU = models.ForeignKey('GPUModel', verbose_name='Видеокарта', on_delete=models.CASCADE, blank=True, null=True) RAM = models.ForeignKey('RAMModel', verbose_name='Оперативная память', on_delete=models.CASCADE, blank=True, null=True) Motherboard = models.ForeignKey( 'MotherboardModel', verbose_name='Материнская плата', on_delete=models.CASCADE, blank=True, null=True ) HDD = models.ForeignKey('HDDModel', verbose_name='HDD', on_delete=models.CASCADE, blank=True, null=True) SSD = models.ForeignKey('SSDModel', verbose_name='SSD', on_delete=models.CASCADE, blank=True, null=True) Power_suppy = models.ForeignKey('Power_suppyModel', verbose_name='Блок питания', on_delete=models.CASCADE, blank=True, null=True) Case = models.ForeignKey('CaseModel', verbose_name='Корпус', on_delete=models.CASCADE, blank=True, null=True) purchase_price = models.IntegerField('Стоимость покупки', default=0) # 采购成本 cost_of_sale = models.IntegerField('Стоимость продажи', default=0) # 售价 profit = models.IntegerField('Прибыль', default=0) # 利润 slug = models.SlugField(unique=True, blank=True, null=True) sold = models.BooleanField('Статус', default=False) # 是否售出 def __str__(self): return self.PC_name def get_absolute_url(self): return reverse("pcmodel_detail", kwargs={"slug": self.slug}) def save(self, *args, **kwargs): self.slug = self.slug super(PCModel, self).save(*args, **kwargs)
CPUModel模型
class CPUModel(models.Model): manufacturer = models.CharField(max_length=15, choices=manufacturer_choice) # 制造商 name = models.CharField(max_length=50) # 型号名称 number_of_cores = models.IntegerField('Количество ядер', choices=number_choice) # 核心数 number_of_threads = models.IntegerField('Количество потоков', choices=number_choice) # 线程数 base_frequency = models.IntegerField('Базовая частота', choices=frequency_choice) # 基础频率 turbo_boost = models.IntegerField('Частота Turbo boost', choices=frequency_choice) # 睿频 socket = models.IntegerField('Сокет', choices=socket_choice) # 插槽类型 TDP = models.IntegerField('Тепловыделение (TDP)', choices=TDP_choice) # 热设计功耗 RAM_type = models.CharField('Поддерживаемый тип памяти', choices=RAM_type_choice, max_length=5) # 支持内存类型 purchase_price = models.IntegerField('Цена закупки') # 采购价格 count = models.IntegerField('Количество') # 库存数量 in_stock = models.BooleanField('Наличие', default=False) # 是否有货 def __str__(self): return self.name def __int__(self): return self.purchase_price def get_purchase(self): return self.purchase_price
修正后的表单代码
class AddPCForm(forms.ModelForm): # 原代码字段名错误,改为与模型匹配的CPU CPU = forms.ModelChoiceField(label='Процессор', queryset=CPUModel.objects.all(), empty_label='请选择处理器') class Meta: model = PCModel fields = [ 'PC_name', 'CPU', 'GPU', 'RAM', 'Motherboard', 'HDD', 'SSD', 'Power_suppy', 'Case', 'purchase_price', 'sold' ]
实现方案
方案一:前端AJAX实时填充(推荐,用户选择时立即生效)
通过前端监听CPU选择框的变化,异步请求后端获取对应CPU的采购价格并自动填充。
1. 新增后端API视图
在views.py中添加获取CPU价格的视图:
from django.http import JsonResponse from .models import CPUModel def get_cpu_price(request): cpu_id = request.GET.get('cpu_id') if cpu_id: try: cpu = CPUModel.objects.get(id=cpu_id) return JsonResponse({'price': cpu.purchase_price}) except CPUModel.DoesNotExist: return JsonResponse({'price': 0}) return JsonResponse({'price': 0})
2. 配置URL路由
在urls.py中添加对应路由:
from django.urls import path from . import views urlpatterns = [ # 其他路由... path('get-cpu-price/', views.get_cpu_price, name='get_cpu_price'), ]
3. 前端模板添加JavaScript
在渲染表单的模板(如add_pc.html)中加入以下代码:
<script> const cpuSelect = document.getElementById('id_CPU'); const purchasePriceInput = document.getElementById('id_purchase_price'); cpuSelect.addEventListener('change', function() { const cpuId = this.value; if (cpuId) { fetch(`/get-cpu-price/?cpu_id=${cpuId}`) .then(response => response.json()) .then(data => purchasePriceInput.value = data.price) .catch(() => purchasePriceInput.value = 0); } else { purchasePriceInput.value = 0; } }); </script>
方案二:后端保存时自动填充(仅确保数据正确性)
如果不需要前端实时显示,可修改PCModel的save方法,在保存时自动同步CPU价格:
def save(self, *args, **kwargs): # 同步CPU采购价格 if self.CPU: self.purchase_price = self.CPU.purchase_price # 优化slug生成逻辑(原代码无实际作用) if not self.slug: self.slug = slugify(self.PC_name) super(PCModel, self).save(*args, **kwargs)
关于CPUModel.objects.raw()的说明
完全不需要使用原生SQL查询,Django ORM的get/filter方法已经能简洁高效地获取CPU对象及价格,比原生SQL更易维护。
内容的提问来源于stack exchange,提问作者JDie
相关产品推荐
相关产品推荐

