【问题标题】:is there a way to convert a view function to a celery task?有没有办法将视图函数转换为芹菜任务?
【发布时间】:2018-04-13 05:39:02
【问题描述】:

task.py

@task(name="send_mail_to_custormer")
def order_created(order_id):
    order = Order.objects.get(id=order_id)
    subject = 'Order nr. {}'.format(order.id)
    message = 'Dear {} {},\n\nYou have successfully placed an order. Your order id is {}'.format(order.first_name,
                                                        order.last_name, order.id)
    from_email = settings.EMAIL_HOST_USER
    to_email = [order.email]
    mail_sent = send_mail(
                            subject,
                            message,
                            from_email,
                            to_email,
                            fail_silently=False
                          )
    return mail_sent

views.py

def order_create(request):
cart = Cart(request)
if request.method == 'POST':
    form = OrderCreateForm(request.POST)
    if form.is_valid():
        order = form.save()
        for item in cart:
            try:
                OrderItem.objects.create(order=order,
                                         product=item['product'],
                                         price=item['price'],
                                         quantity=item['quantity'])
            except:
                pass
            cart.clear()
            order_created.delay(order.id)
        return render(request,'orders/order_created.html', {'cart': cart, 'order': order})
else:
    form = OrderCreateForm()
return render(request, 'orders/order_create.html', {'cart': cart, 'form': form})

cart.py

class Cart(object):

def __init__(self, request):
    self.session = request.session
    cart = self.session.get(settings.CART_SESSION_ID)
    if not cart:
        cart = self.session[settings.CART_SESSION_ID] = {}
    self.cart = cart

def add(self, product, quantity=1, update_quantity=False):
    product_id = str(product.id)
    if product_id not in self.cart:
        self.cart[product_id] = {'quantity': 0,
                                 'price': str(product.price)}
    if update_quantity:
        self.cart[product_id]['quantity'] = quantity
    else:
        self.cart[product_id]['quantity'] += quantity
    self.save()

def save(self):
    self.session[settings.CART_SESSION_ID] = self.cart
    self.session.modified = True

现在 celery 任务发送邮件,查看功能在从购物车和订单表格中获取值后创建订单。如何更改任务以创建订单?这样做是不是一个好习惯。希望有人可以帮助我,谢谢。也可以使用 django 消息框架作为 celery 任务来发送成功消息吗?

【问题讨论】:

    标签: python django celery


    【解决方案1】:

    我不会也不会(在我的公司中,我们经营着几家网上商店)异步创建订单。当用户看到您的感谢页面时,您最好确保已创建订单。毕竟这只是几个数据库操作,页面速度不会成为问题。但是,邮件发送是不应延长请求-响应周期的任务的典型示例。不过有一件事:您可能需要考虑让您的任务安全延迟几秒钟:

    order_created.apply_async(args=[order.id], countdown=5)
    

    订单刚刚创建,并且 - 特别是如果您为数据库设置了原子请求 - 任务工作人员可以在订单创建事务被提交并且对工作人员可见之前查询订单。或者,您可以使用 transaction.on_commit 挂钩来避免这种竞争条件。

    【讨论】:

    • 非常感谢您的回复,这不是一个真实的用例,客户希望将订单创建视为芹菜任务。
    • 好吧,那么您必须将所有与购物车相关的会话数据序列化为适当的任务参数 :) 顺便说一句,对于消息问题:我想您必须将一些 UserMessage 模型写入数据库并在相应用户的下一个请求出现时使用一些自定义中间件。
    猜你喜欢
    • 2021-04-16
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 2013-02-23
    • 2017-01-22
    相关资源
    最近更新 更多