【问题标题】:How to write proper condition in pre_save signal in Django如何在 Django 的 pre_save 信号中写入正确的条件
【发布时间】:2022-01-13 22:03:07
【问题描述】:

我刚刚开始了我的 IT 职业生涯,当时我还是一名 Python/Django 的大三学生。目前我正在 Python/Django 后端处理我们商店的库存/库存部分。

Order.status 被更改为@987654325 时,我想做的是在ItemModel 中更改Item 中的quantity(这是两个不同的模型-ItemModel 是各种配置中的项目的模型) @ - 客户在下订单后触发操作(例如银行确认付款)以及在管理面板中手动设置时。所以我在这样的函数上设置了信号:

@receiver(post_save, sender=Order)
def update_stock(sender, instance, created, **kwargs):
    status_values = [order.status for order in instance.status_history.all()]
    if instance.status == OrderStatus.PAID and instance.status not in status_values:
       stock_to_change = []
       # do something to change the stock quantity in loops
       # Take ItemModel.object -> create StockMove.object
问题从这里开始:

即使Order 是第一次以 PAID 状态创建,它的状态历史记录中也会有 PAID 值,因为它是 post_save,所以刚刚创建的状态已经存在。所以我想到的是-好的,将第二个条件更改为instance.status not in status_values[:1]。但它不起作用 - 因为在上述情况下以及在任何其他具有当前 PAID 状态的订单中,它将返回一个没有 PAID 值的列表(这是列表中的最后一个),因此订单的每次更改(例如新的送货地址)都会改变库存数量订购产品的数量(当状态设置为第一次付款时,它应该只更新一次。PAID != status_values)。

我花了一整天的时间来解决这个问题,但我放弃了。我应该只覆盖 order.model 中的 save() 方法吗?感谢您的任何建议!

【问题讨论】:

  • 请分享您的模型,否则我很难理解这一点

标签: python django django-models django-signals


【解决方案1】:

我想我已经找到了答案,也许不是一个漂亮的答案,但它可以按我的意愿工作。

@receiver(post_save, sender=Order)
def update_stock(sender, instance, created, update_fields, **kwargs):
    status_values = [order.status for order in instance.status_history.all()]

    # Do the rest of the code when Order with status PAID Created=True 
    # or order.status was updated to PAID value 
    # and PAID value is not in OrderStatusHistory.

    if instance.status == OrderStatus.PAID:
        if instance.status not in status_values[:-1]:
            if created or (update_fields is not None and 'status' in update_fields): 
                stock_to_change = []

要工作,它还需要覆盖OrderAdmin 中的save_model()

@admin.register(models.Order)
class OrderAdmin(admin.ModelAdmin):
    
    ...

    def save_model(self, request, obj, form, change):
        update_fields = []

        if change: 
            if form.initial['status'] != form.cleaned_data['status']:
                update_fields.append('status')


        obj.save(update_fields=update_fields)
        return super(OrderAdmin, self).save_model(request, obj, form, change)

【讨论】:

    猜你喜欢
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    • 2011-09-03
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 2010-11-02
    相关资源
    最近更新 更多