Reputation: 39
I'm trying to make an eCommerce site with Django and I've been following along with this online course as well as the docs.
And as I was updating the login forms to have better UX I came across an error in my carts view. Which I thought was strange because I didn't change anything in the order or the checkout view in my cart app. So here is the full traceback:
>Environment:
>
>
>Request Method: GET
>Request URL: root/cart/checkout/
>
>Django Version: 2.2.12
>Python Version: 3.6.9
>Installed Applications:
>['django.contrib.admin',
> 'django.contrib.auth',
> 'django.contrib.contenttypes',
> 'django.contrib.sessions',
> 'django.contrib.messages',
> 'django.contrib.staticfiles',
> 'storages',
> 'accounts',
> 'addresses',
> 'analytics',
> 'billing',
> 'carts',
> 'marketing',
> 'orders',
> 'products',
> 'search',
> 'tags']
>Installed Middleware:
>['django.middleware.security.SecurityMiddleware',
> 'django.contrib.sessions.middleware.SessionMiddleware',
> 'django.middleware.common.CommonMiddleware',
> 'django.middleware.csrf.CsrfViewMiddleware',
> 'django.contrib.auth.middleware.AuthenticationMiddleware',
> 'django.contrib.messages.middleware.MessageMiddleware',
> 'django.middleware.clickjacking.XFrameOptionsMiddleware']
>
>
>
>Traceback:
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/core/handlers/exception.py" in >inner
> 34. response = get_response(request)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/core/handlers/base.py" in >_get_response
> 115. response = self.process_exception_by_middleware(e, request)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/core/handlers/base.py" in >_get_response
> 113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
>
>File "/home/ray/Dev/rxvenv/src/carts/views.py" in checkout_home
> 79. login_form = LoginForm()
>
>Exception Type: TypeError at /cart/checkout/
>Exception Value: __init__() missing 1 required positional argument: 'request'
According to the traceback my error is coming from src/carts/view.py, specifically by my call to LoginForm. Here is the file where the exception is raising, but I'm leaving out some of the code out to not be too verbose.
So the error is being cause when I call LoginForm. LoginForm has to be the root of the problem because that's the only thing I've changed since the last time I tested the cart checkout views. It must've been in one of my recent changes so hereit is:
# src/accounts/forms.py
from django import forms
from django.contrib.auth import authenticate, login, get_user_model
from django.urls import reverse
from django.utils.safestring import mark_safe
User = get_user_model()
class LoginForm(forms.Form):
email = forms.EmailField(label='Email')
password = forms.CharField(widget=forms.PasswordInput)
# the error is saying "__init__() missing 1 required positional argument: 'request':
# so that must mean that the error is being caused by a call or this definition
def __init__(self, request, *args, **kwargs):
self.request = request
super(LoginForm, self).__init__(*args, **kwargs)
def clean(self):
request = self.request
data = self.cleaned_data
email = data.get("email")
password = data.get("password")
qs = User.objects.filter(email=email)
if qs.exists():
# user email is registered, check active/
not_active = qs.filter(is_active=False)
if not_active.exists():
## not active, check email activation
link = reverse("account:resend-activation")
reconfirm_msg = """Go to <a href='{resend_link}'>
resend confirmation email</a>.
""".format(resend_link = link)
confirm_email = EmailActivation.objects.filter(email=email)
is_confirmable = confirm_email.confirmable().exists()
if is_confirmable:
msg1 = "Please check your email to confirm your account or " + reconfirm_msg.lower()
raise forms.ValidationError(mark_safe(msg1))
email_confirm_exists = EmailActivation.objects.email_exists(email).exists()
if email_confirm_exists:
msg2 = "Email not confirmed. " + reconfirm_msg
raise forms.ValidationError(mark_safe(msg2))
if not is_confirmable and not email_confirm_exists:
raise forms.ValidationError("This user is inactive.")
user = authenticate(request, username=email, password=password)
if user is None:
raise forms.ValidationError("Invalid credentials")
login(request, user)
self.user = user
return data
# src/carts/views.py
from django.shortcuts import render, redirect
from accounts.forms import LoginForm, GuestForm
from accounts.models import GuestEmail
from addresses.forms import AddressForm
from addresses.models import Address
from billing.models import BillingProfile
from orders.models import Order
from products.models import Product
from .models import Cart
def checkout_home(request):
cart_obj, cart_created = Cart.objects.new_or_get(request)
order_obj = None
if cart_created or cart_obj.products.count() == 0:
return redirect("cart:home")
print('request', request)
login_form = LoginForm() #this line is causing an error
guest_form = GuestForm()
address_form = AddressForm()
billing_address_id = request.session.get("billing_address_id", None)
shipping_address_id = request.session.get("shipping_address_id", None)
billing_profile, billing_profile_created = BillingProfile.objects.new_or_get(request)
address_qs = None
has_card = False
if billing_profile is not None:
if request.user.is_authenticated:
address_qs = Address.objects.filter(billing_profile=billing_profile)
order_obj, order_obj_created = Order.objects.new_or_get(billing_profile, cart_obj)
if shipping_address_id:
order_obj.shipping_address = Address.objects.get(id=shipping_address_id)
del request.session["shipping_address_id"]
if billing_address_id:
order_obj.billing_address = Address.objects.get(id=billing_address_id)
del request.session["billing_address_id"]
if billing_address_id or shipping_address_id:
order_obj.save()
has_card = billing_profile.has_card
if request.method == "POST":
"check that order is done"
is_prepared = order_obj.check_done()
if is_prepared:
did_charge, crg_msg = billing_profile.charge(order_obj)
if did_charge:
order_obj.mark_paid()
request.session['cart_items'] = 0
del request.session['cart_id']
if not billing_profile.user:
'''
is this the best spot?
'''
billing_profile.set_cards_inactive()
return redirect("cart:success")
else:
print(crg_msg)
return redirect("cart:checkout")
context = {
"object": order_obj,
"billing_profile": billing_profile,
"login_form": login_form,
"guest_form": guest_form,
"address_form": address_form,
"address_qs": address_qs,
"has_card": has_card
}
return render(request, "carts/checkout.html", context)
Upvotes: 0
Views: 368
Reputation: 15738
Your LoginForm
form __init__
has request as positional argument but you are not providing it
login_form = LoginForm(request)
Upvotes: 2