Reputation: 1
even though user5 is in the user table but when I login It gives me this message
ValueError at / Cannot query "user5": Must be "Customer" instance.
Here are the models of my website.
This website also enables you to checkout without having an account.
Here is more information about the code, This shows the complete stack trace, I hope now its more understandable.
models.py
class Customer(models.Model):
customer = models.OneToOneField(User, on_delete=models.CASCADE, related_name = 'customer', null=True, blank=True)
name = models.CharField(max_length= 200, null=True)
email = models.CharField(max_length=200, null=True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return self.name
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete= models.SET_NULL, blank=True, null=True)
date_ordered = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False, blank=False, null=True)
transaction_id = models.CharField(max_length=200, null=True)
def __str__(self):
return str(self.id)
@property
def shipping(self):
shipping=False
orderitems = self.orderitem_set.all()
for i in orderitems:
if i.product.digital == False:
shipping=True
return shipping
@property
def get_cart_total(self):
orderitems = self.orderitem_set.all()
total = sum([item.get_total for item in orderitems])
return total
@property
def get_cart_items(self):
orderitems = self.orderitem_set.all()
total = sum([item.quantity for item in orderitems])
return total
views.py
def store(request):
data = cartData(request)
cartItems = data['cartItems']
products = Product.objects.all()
context = {'products' : products, 'cartItems' :cartItems}
return render(request, 'store/store.html',context)
def cart(request):
data = cartData(request)
cartItems = data['cartItems']
order = data['order']
items = data['items']
context ={'items' :items, 'order': order, 'cartItems' :cartItems}
return render(request, 'store/cart.html',context)
def checkout(request):
data = cartData(request)
cartItems = data['cartItems']
order = data['order']
items = data['items']
context ={'items' :items, 'order': order, 'cartItems' :cartItems}
return render(request, 'store/checkout.html',context)
def updateItem(request, customer):
data = json.loads(request.body)
productId = data['productId']
action = data['action']
print('Action: ',action)
print('productId: ',productId)
customer = request.user.customer
product = Product.objects.get(id = productId)
order, created = Order.objects.get_or_create(customer = customer, complete= False)
orderItem, created = OrderItem.objects.get_or_create(order= order, product= product)
if action=='add':
orderItem.quantity = (orderItem.quantity + 1)
elif action == 'remove' :
orderItem.quantity = (orderItem.quantity - 1)
orderItem.save()
if orderItem.quantity <= 0:
orderItem.delete()
return JsonResponse('item added', safe=False)
def processOrder(request, customer):
transaction_id = datetime.datetime.now().timestamp()
data = json.loads(request.body)
if(request.user.is_authenticated):
customer = request.user.customer
order, created = Order.objects.get_or_create(customer = customer, complete= False)
else:
customer, order = guestOrder(request, data)
total = float(data['form']['total'])
order.transaction_id = transaction_id
if total==float(order.get_cart_total):
order.complete = True
order.save()
if order.shipping == True:
ShippingAddress.objects.create(
customer = customer,
order = order,
address = data['shipping']['address'],
city = data['shipping']['city'],
state = data['shipping']['state'],
zipcode = data['shipping']['zipcode'],
)
return JsonResponse('Payment complete!', safe=False)
def registerPage(request):
form = CreateUserForm()
if request.method=="POST":
form = CreateUserForm(request.POST)
if form.is_valid():
form.save()
user = form.cleaned_data.get('username')
messages.success(request, "Account created successfully for "+user)
return redirect('login')
context = {'form': form}
return render(request, 'store/registration.html', context
def loginPage(request):
if request.method=="POST":
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user:
login(request, user)
messages.success(request, "Logged In")
return redirect('store')
else:
messages.error(request, "Invalid Credentials")
return redirect("login")
context = {}
return render(request, 'store/login.html', context)
utils.py
def cookieCart(request):
try:
cart = json.loads(request.COOKIES['cart'])
except:
cart={}
print('Cart: ',cart)
items = []
order = {'get_cart_total':0, 'get_cart_items':0, 'shipping': False}
cartItems = order['get_cart_items']
for i in cart:
try:
cartItems += cart[i]['quantity']
product = Product.objects.get(id=i)
total = (product.price * cart[i]['quantity'])
order['get_cart_total'] += total
order['get_cart_items'] += cart[i]['quantity']
item = {
'product':{
'id':product.id,
'name': product.name,
'price': product.price,
'imageURL': product.imageURL,
},
'quantity': cart[i]['quantity'],
'get_total' : total
}
items.append(item)
if product.digital == False:
order['shipping'] = True
except:
pass
return{'cartItems':cartItems, 'order':order, 'items':items}
def cartData(request):
if request.user.is_authenticated:
customer = request.user
order, created = Order.objects.get_or_create(customer = customer, complete= False)
items = order.orderitem_set.all()
cartItems = order.get_cart_items
else:
cookieData=cookieCart(request)
cartItems = cookieData['cartItems']
order = cookieData['order']
items = cookieData['items']
return {'cartItems':cartItems, 'order':order, 'items':items}
def guestOrder(request, data):
print('User not logged in')
print('COOKIES: ',request.COOKIES)
name = data['form']['name']
email = data['form']['email']
cookieData = cookieCart(request)
items = cookieData['items']
customer, created = Customer.objects.get_or_create(
email = email,
)
customer.name = name
customer.save()
order = Order.objects.create(
customer = customer,
complete = False,
)
for item in items:
product = Product.objects.get(id= item['product']['id'])
orderItem = OrderItem.objects.create(
product = product,
order = order,
quantity=item['quantity']
)
return customer, order
settings.py
import os
from django.contrib.messages import constants as messages
MESSAGE_TAGS = {
messages.DEBUG: 'alert-secondary',
messages.INFO: 'alert-info',
messages.SUCCESS: 'alert-success',
messages.WARNING: 'alert-warning',
messages.ERROR: 'alert-danger',
}
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'a=m+1^c$evt6l5$f=(9ea^7n7r#r8rpjdu57&(((8ms(gvx2g('
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'store.apps.StoreConfig',
]
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',
]
ROOT_URLCONF = 'GetItNow.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'template')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'GetItNow.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
VENV_PATH = os.path.dirname(BASE_DIR)
STATIC_ROOT = os.path.join(VENV_PATH, 'static_root')
MEDIA_URL = '/images/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/images')
Upvotes: 0
Views: 519
Reputation: 23
Though your codes are not providing the details of the actual problem. But from them what I can understand is that your User table has a 1to1 relation with the Customer table and you are allowing a non registered customer to check out. The problem is when you are checking out with an unregistered customer then the User is anonymous and that anonymous user doesn't have any detail on the Customer Table. So the exception is raised.
What you have to do is to simply change the Order model customer relationship with the User table and not with the Customer table. If you change it then if you are using Django default anonymous user for a non signed user then it will automatically get Django Anonymous user for a non signed user and you do not have to worry about the customer detail of a user.
class Customer(models.Model):
customer = models.OneToOneField(User, on_delete=models.CASCADE, related_name = 'customer', null=True, blank=True)
name = models.CharField(max_length= 200, null=True)
email = models.CharField(max_length=200, null=True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return self.name
class Order(models.Model):
customer = models.ForeignKey(User, on_delete= models.SET_NULL, blank=True, null=True)
date_ordered = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False, blank=False, null=True)
transaction_id = models.CharField(max_length=200, null=True)
def __str__(self):
return str(self.id)
Upvotes: 1