Django 模型 - 自动刷新字段值

Django Models - Auto-Refresh field value

在我的 django models.py 中,我使用 lxml 从亚马逊抓取商品价格。 当我在管理页面中点击保存时,它会将此价格存储在 "price" 字段中,但有时亚马逊价格会发生变化,所以我想每 2 天自动更新一次价格。这是我现在的职能:

class AmazonItem(models.Model):
    amazon_url = models.CharField(max_length=800, null=True, blank=True)
    price = models.DecimalField(max_digits=6, decimal_places=2, editable=False)
    last_update = models.DateTimeField(editable=False)

def save(self):
    if not self.id:
        if self.amazon_url:
            url = self.amazon_url
            source_code = requests.get(url)
            code = html.fromstring(source_code.text)
            prices = code.xpath('//span[@id="priceblock_ourprice"]/text()')
            eur = prezzi[0].replace("EUR ", "")
            nospace = eur.replace(" ", "")
            nodown = nospace.replace("\n", "")
            end = nodown.replace(",", ".")
            self.price = float(end)
        else:
            self.price = 0

    self.last_update = datetime.datetime.today()
    super(AmazonItem, self).save()

我真的不知道该怎么做,我只想让它自动完成

隔离同步功能

首先我将同步功能从保存中分离出来,例如你可以创建一个 AmazonItem.sync() 方法

def sync(self):
    # Your HTTP request and HTML parsing here
    # Update self.price, self.last_updated etc

使用管理命令的 Cron 作业

现在,您的起点是对要同步的模型实例调用 .sync()。一个非常粗略*的方法是:

for amazon_item in AmazonItem.objects.all():
    amazon_item.sync()
    amazon_item.save()

你可以,例如将该代码放入名为 sync_amazon_itemsDjango Command 中,并每 2 天 运行 设置一个 cron 作业

# app/management/commands/sync_amazon_items.py
class Command(BaseCommand):
    def handle(self, *args, **options):
        for amazon_item in AmazonItem.objects.all():
            amazon_item.sync()
            amazon_item.save()

然后你可以让你的 OS 或作业调度程序 运行 它,例如使用 python manage.py sync_amazon_items

* 这将非常慢,因为它会按顺序遍历您的列表,而且任何项目中的错误都会停止操作,因此您需要捕获异常记录它们并继续前进,例如

使用任务队列/调度程序

一种性能更可靠(隔离故障)的方法是将同步作业(例如每个 amazon_item 的作业或一批 N amazon_item 的作业)排队到作业队列中,例如Celery,然后将 Celery 并发设置为 运行 当前

几个同步作业

要使用 Celery 安排周期性任务,请查看 Periodic Tasks