python
  • django
  • celery
  • 2017-10-31 2 views 2 likes 
    2

    task.pyGibt es eine Möglichkeit, eine Ansichtsfunktion in eine Sellerie-Aufgabe zu konvertieren?

    @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 
    

    Nun sendet der Sellerie Aufgabe Werte von Warenkorb und bestellen, um nach Post und View-Funktion schafft unter bilden. Wie kann ich die Aufgabe ändern, um eine Bestellung zu erstellen? Ist es eine gute Übung, dies zu tun? Hoffe jemand kann mir helfen, danke. Ist es auch möglich, eine Erfolgsmeldung mit dem Django Message Framework als Sellerie-Aufgabe zu machen?

    Antwort

    2

    Ich würde nicht und nicht (in meiner Firma führen wir ein paar Webshops) erstellen Sie die Bestellung asynchron. Wenn der Benutzer Ihre Dankeseite sieht, sollten Sie sicher sein, dass eine Bestellung erstellt wurde. Es sind nur ein paar db-Operationen, und die Seitengeschwindigkeit wird kein Problem sein. Das Senden von E-Mails ist jedoch ein klassisches Beispiel für eine Aufgabe, die Ihren Anfrage-Antwort-Zyklus nicht dehnen sollte. Eine Sache aber: Man könnte in Erwägung ziehen, Ihre Aufgabe, eine Sicherheitsverzögerung von ein paar Sekunden zu geben:

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

    Der Auftrag wurde gerade erstellt und - vor allem, wenn Sie Atom haben Anfragen für die Datenbank festgelegt - die Aufgabe Arbeiter könnte die Bestellung abfragen, bevor die Auftragserstellungstransaktion festgeschrieben wurde und für den Arbeiter sichtbar wird. Alternativ können Sie den Haken transaction.on_commit verwenden, um diesen Wettlauf zu vermeiden.

    +0

    Vielen Dank für Ihre Antwort, dies ist kein echter Anwendungsfall, Client möchte die Auftragserstellung als Sellerie Aufgabe sehen. – user6837382

    +0

    Nun, dann müssen Sie alle Ihre Warenkorb verbundenen Sitzungsdaten zu den richtigen Aufgabenargumente serialisieren :) BTW, für die Nachricht Frage: Ich denke, Sie müssten ein 'UserMessage' Modell in die Datenbank schreiben und einige benutzerdefinierte Middleware wählen wenn die nächste Anfrage des entsprechenden Benutzers kommt. – schwobaseggl

    +0

    Nochmals vielen Dank – user6837382

    Verwandte Themen