Omar Gonzales
Omar Gonzales

Reputation: 4008

Django: store value after user logs in or signs up

I need to create a random value when user stars session and store it after user logs in or signs up. Must be deleted after user logs out.

I'm using session.session_key, but could be anyother random value.

Why session.session_key? Because it gets automatically generated when user enters website.

When user enters website they can add items to their shopping cart, but cannot buy until logs in or signs up. All cart_items use the random value as a token, so if I can save this value after user logs in or signs up I can query the cart_items that are already saved in DB and restore items user had already put in this shopping cart.

So when user enters a new session.session_key is created but after user logs in or signs up another session.session_key is created. Making it impossible to use this value to establish a flow between user not logged in and user logged in.

My logic:

1.- Save session.session_key in Cookie.
2.- After user logs in or signs up a new session.session_key is created. We need to replace this new session.session_key with the one saved in Cookie.
3.- Get old session.session_key to query all objects created using this value as an ID and do stuff.

Code:

cart id that need to be stored is generated with this function:

def _cart_id(request):
    cart = request.session.session_key

    if not cart:
        request.session.create()  
        cart = request.session.session_key
    return cart  # Ultimately return cart

SignUp View:

@transaction.atomic
def signupView(request):

    if request.method == 'POST':

      ...do stuff ...

    ### Save cart id in Cookie before authenticating
            set_cookie_values(request)
    ### Authentication
            user = authenticate(username=username, password=raw_password)
            login(request, user)

            ### Get cart id from Cookie
            cart = request.COOKIES.get('cart', '')


            delete_cookie_values(request)

            return redirect('cart:cart_detail')
    else:

        profile_form = ProfileForm(district_list, province_list, department_list)
    return render(request, 'accounts/signup.html', {
        'user_form': user_form,
        'profile_form': profile_form
})

Helpers to store and delete value from Cookie:

def set_cookie_values(request):
    try:
        cart_id =_cart_id(request)
        response = HttpResponse()
        response.set_cookie('cart_id', cart_id, max_age=9999999999)

    except ObjectDoesNotExist:
        pass

    return response


def delete_cookie_values(request):
    response = HttpResponse()
    response.delete_cookie('cart_id')
    return response

I'd appreaciate your help checking out my pseudo code for storing cart_id on Cookie and retrive it.

UPDATE 1:

After Daniel Roseman's comment, I think I need to store the cart_id in session, delete it when user logs out, generate a new 1 when user ads a new item to the cart, delete it when logs out and so on.

I want to do it in the form that saves the OrderItem of user, but I don't know exaclty how to do it:

import secrets

# Create your views here.

def _cart_id(request):
    if 'cart_id' in request.session:
        cart_id = request.session['cart_id']
    else:
        cart_id = secrets.token_urlsafe(22)
    return cart_id 

Form Class:

class StepTwoView(CreateView):
    form_class = StepTwoForm
    template_name = 'shop/subir-arte.html'
    success_url = '/cart/'


    def get_initial(self):
        initial = super(StepTwoView, self).get_initial()
        initial['cart_id'] = secrets.token_urlsafe(22)


    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['product'] = Product.objects.get(
            category__slug=self.kwargs['c_slug'],
            slug=self.kwargs['product_slug']
        )
        return context

    def form_valid(self, form):

        try:
            cart = Cart.objects.get(cart_id=_cart_id(self.request))
        except Cart.DoesNotExist:
            cart = Cart.objects.create(
                    cart_id = _cart_id(self.request)
                )

            cart.save()

        self.request.session['cart_id'] = self.initial['cart_id']

        form.instance.cart = cart
        form.instance.product = Product.objects.get(
            category__slug=self.kwargs['c_slug'],
            slug=self.kwargs['product_slug']
        )  # get tamanios from session
        form.instance.size = self.request.session.get('size')  # get tamanios from session
        form.instance.quantity = self.request.session.get('quantity')  # get cantidades from session
        del self.request.session['quantity']  # delete cantidades value from session
        del self.request.session['size']  # delete tamanios value from session
        self.request.session.modified = True
        return super(StepTwoView, self).form_valid(form)

But I'm getting:

KeyError at /shop/stickers/stickers-cuadrados/subir-arte

'cart_id'

self.request.session['cart_id'] = self.initial['cart_id']

Upvotes: 0

Views: 213

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599876

You're doing things the wrong way round. The session key is renewed when a user logs in, but the contents of the session are preserved. So what you should do is to give the cart a separate random ID, and store that in the session.

Upvotes: 1

Related Questions