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

Django实现无需入库存储的商品实时动态价格计算方案咨询

第一步:配置Django缓存(必做,避免重复爬取)

先在项目settings.py中添加缓存配置,小站点用默认本地内存缓存即可,用来存每日原材料价格,一天只爬一次:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'daily-price-cache',
    }
}
第二步:优化原材料价格爬取函数

把爬取函数放到models.py顶部,加缓存逻辑、异常处理和类型转换,避免和模型Decimal字段计算出现精度问题:

from django.core.cache import cache
from decimal import Decimal
import requests
from bs4 import BeautifulSoup

def get_prixmatiere():
    # 先读缓存,缓存有效期24小时=86400秒
    cache_key = "daily_raw_material_price"
    cached_price = cache.get(cache_key)
    if cached_price:
        return cached_price
    # 缓存不存在才发起爬取
    try:
        response = requests.get("https://www.exampl.com", timeout=10)
        response.raise_for_status()
        soup = BeautifulSoup(response.text, 'lxml')
        product_price = soup.find_all("td",{"class" : "price"})[0].text.replace('€', '').replace(' ', '')
        prixmatiere = float(product_price) / 4 * 3 / 1000 * 210
        # 转成Decimal和模型字段类型匹配,保留两位小数
        prixmatiere = Decimal(str(prixmatiere)).quantize(Decimal('0.00'))
        cache.set(cache_key, prixmatiere, 86400)
        return prixmatiere
    except:
        # 爬取失败返回默认值,可根据业务需求调整 fallback 逻辑
        return Decimal('0.00')
第三步:给Product模型加动态价格属性

把计算方法放到Product类内部,加@property装饰器,前端可以直接调用属性获取价格,原有模型字段完全不用改:

class Product(models.Model):
    # 原有字段保持不变
    prdct_name = models.CharField(max_length=17, verbose_name=_("Article "))
    prdct_category = models.ForeignKey("Category", on_delete=models.CASCADE, blank=True, null=True)
    prdct_description = models.TextField(verbose_name=_("Description"))
    prdct_img = models.ImageField(upload_to='product/',verbose_name=_("Image"), blank=True, null=True)
    prdct_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name=_("Prix "))
    prdct_cost = models.DecimalField(max_digits=10, decimal_places=2, verbose_name=_("Prix promotionel "))
    prdct_weight = models.DecimalField(max_digits=10, decimal_places=2, verbose_name=_("Poid "))
    prdct_created = models.DateTimeField(auto_now=False, auto_now_add=False, verbose_name=_("Date Creation "))
    prdct_genre = models.CharField(max_length=50, verbose_name=_("Genre "))
    prdct_matiere = models.CharField(max_length=50, verbose_name=_("Matiere "))
    prdct_titrage = models.CharField(max_length=50, verbose_name=_("titrage "))
    prdct_in_stock = models.BooleanField(verbose_name=_("in_stock "))
    prdct_slug = models.SlugField(blank=True, null=True)

    # 新增动态价格属性
    @property
    def calc_price_item(self):
        dailyprice = get_prixmatiere()
        item_price = self.prdct_price + dailyprice * self.prdct_weight
        return item_price.quantize(Decimal('0.00'))
第四步:模板层直接展示价格

现有views.py代码完全不用修改,直接在对应的HTML模板里调用属性即可:

  1. 商品列表页product_list.html:
{% for product in product_list %}
<div>
    <h4>{{ product.prdct_name }}</h4>
    <p>今日售价:€{{ product.calc_price_item }}</p>
</div>
{% endfor %}
  1. 商品详情页product_detail.html:
<h2>{{ product_detail.prdct_name }}</h2>
<p>当前售价:€{{ product_detail.calc_price_item }}</p>
  1. 分类商品页category_product.html:
{% for item in product %}
<div>
    <h4>{{ item.prdct_name }}</h4>
    <p>今日售价:€{{ item.calc_price_item }}</p>
</div>
{% endfor %}
可选优化

如果对页面响应速度要求高,可以用定时任务(Django Crontab/Celery)每天固定时间爬取价格更新到缓存,用户访问时直接读缓存,完全不用实时爬取,响应速度更快。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 07:18:05