S
S
SilvestrVStolovoy2021-02-27 13:34:33
Django
SilvestrVStolovoy, 2021-02-27 13:34:33

How to place an order for an anonymous user?

Hello! I started making an online store, and I ran into such a problem, I can’t normally place an order for an anonymous user. Creating a shopping cart and adding products to it for anonymous users was implemented through sessions like this

class CartMixin(View):

    def dispatch(self, request, *args, **kwargs):
        if not request.session.session_key:
            request.session.save()
        self.session = request.session

        if request.user.is_authenticated:
            customer = Customer.objects.filter(user=request.user).first()
            if not customer:
                customer = Customer.objects.create(user=request.user)
            cart = Cart.objects.filter(owner=customer, in_order=False).first()
            if not cart:
                cart = Cart.objects.create(owner=customer)
        else:
            cart = Cart.objects.filter(session_key=self.session.session_key, for_anonymous_user=True).first()
            if not cart:
                cart = Cart.objects.create(session_key=self.session.session_key, for_anonymous_user=True)
        self.cart = cart
        return super().dispatch(request, *args, **kwargs)


This is a cart model.

class Cart(models.Model):

    owner = models.ForeignKey('Customer', null=True, verbose_name='Владелец', on_delete=models.CASCADE)
    products = models.ManyToManyField(CartProduct, blank=True, related_name='related_cart')
    total_products = models.PositiveIntegerField(default=0)
    final_price = models.DecimalField(max_digits=9, default=0, decimal_places=2, verbose_name='Общая стоимость')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания заказа')
    in_order = models.BooleanField(default=False)
    for_anonymous_user = models.BooleanField(default=False)
    session_key = models.CharField(max_length=32, null=True)


And here everything seems to be fine, baskets are created, goods are added / removed, everything is as it should be. Problems arise when trying to place an order.

The order form in views.py looks like this:

class MakeOrderView(CartMixin, View):

    @transaction.atomic
    def post(self, request, *args, **kwargs):
        form = OrderForm(request.POST or None)
        if request.user.is_authenticated:
            customer = Customer.objects.get(user=request.user)
        if form.is_valid():
            new_order = form.save(commit=False)
            new_order.customer = customer
            new_order.first_name = form.cleaned_data['first_name']
            new_order.last_name = form.cleaned_data['last_name']
            new_order.phone = form.cleaned_data['phone']
            new_order.address = form.cleaned_data['address']
            new_order.buying_type = form.cleaned_data['buying_type']
            new_order.order_date = form.cleaned_data['order_date']
            new_order.comment = form.cleaned_data['comment']
            new_order.save()
            self.cart.in_order = True
            self.cart.save()
            # msg = str(self.cart.products.values('product'))
            # send_mail('Заказ', msg, '[email protected]ndex.ru', ['[email protected]'])
            new_order.cart = self.cart
            new_order.save()
            customer.orders.add(new_order)
            messages.add_message(request, messages.INFO, 'Спасибо за заказ')
            return HttpResponseRedirect('/')
        return HttpResponseRedirect('/checkout/')


As I understand it, there is a mistake in this line, it needs to be improved somehow
if request.user.is_authenticated:
            customer = Customer.objects.get(user=request.user)

It is clear that he cannot get the user if he is anonymous. I tried to create a guest user and bind everything to him, but then after the order, the anonymous cart is not updated. I also found articles that you can make a temporary registration, but I did not manage to implement it. Please tell me how to fix this? Thanks in advance :)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dr. Bacon, 2021-02-27
@SilvestrVStolovoy

Make the Order model have the same fields for an anonymous user as Cart, well, and the same work logic.
Threat at least I would immediately create a user, at the moment when the basket would be needed, perhaps earlier (this is usually what marketers really want) and there would be no need to fence additional work logic.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question