Can anyone please help me to fix this problem local variable 'intent' referenced before assignment i could not find out why client_secret in the context is triggered. to my knowledge if the code in if statement fails then else block will be executed but i have set a print statement and it does not appear in the teminal either. if someone can please help me in solving this issue.
from django.shortcuts import render, redirect, reverse
from django.contrib import messages
from django.conf import settings
from .forms import OrderForm
from .models import Order, OrderLineItem, ProductLineItem, ExerciseLineItem, NutritionLineItem
from merchandise.models import Product
from exercise.models import ExercisePlans
from nutrition.models import NutritionPlans
from cart.contexts import cart_contents
import stripe
def checkout(request):
stripe_public_key = settings.STRIPE_PUBLIC_KEY
stripe_secret_key = settings.STRIPE_SECRET_KEY
if request.method == 'POST':
cart = request.session.get('cart', {
'merchandise_dic': {},
'excercise_plans_dic': {},
'nutrition_plans_dic': {},
})
form_data = {
'full_name': request.POST['full_name'],
'email': request.POST['email'],
'phone_number': request.POST['phone_number'],
'country': request.POST['country'],
'postcode': request.POST['postcode'],
'town_or_city': request.POST['town_or_city'],
'street_address1': request.POST['street_address1'],
'street_address2': request.POST['street_address2'],
'county': request.POST['county'],
}
order_form = OrderForm(form_data)
if order_form.is_valid():
print("Order form is valid")
order = order_form.save()
for product_type, dic in cart.items():
if product_type == 'merchandise_dic':
for item_id, quantity in dic.items():
print(f"This is item id of merchandise: {item_id}")
print(f"This is quantity of merchandise: {quantity}")
product = Product.objects.get(id=item_id)
print(product)
order_line_item = ProductLineItem(
order=order,
product=product,
quantity=quantity,
)
order_line_item.save()
elif product_type == 'excercise_plans_dic':
for item_id, quantity in dic.items():
print(f"This is item id of exercise plan: {item_id}")
print(f"This is quantity of exercise plan: {quantity}")
product = ExercisePlans.objects.get(id=item_id)
print(product)
order_line_item = ExerciseLineItem(
order=order,
product=product,
quantity=quantity,
)
order_line_item.save()
elif product_type == 'nutrition_plans_dic':
for item_id, quantity in dic.items():
print(f"This is item id of nutrition plan: {item_id}")
print(f"This is quantity of nutrition plan: {quantity}")
product = NutritionPlans.objects.get(id=item_id)
print(product)
order_line_item = NutritionLineItem(
order=order,
product=product,
quantity=quantity,
)
order_line_item.save()
else:
print("Order form is invalid")
messages.error(request, ('There was an error with your form. '
'Please double check your information.'))
return redirect(reverse('checkout'))
else:
print("Order form is invalid")
cart = request.session.get('cart', {
'merchandise_dic': {},
'excercise_plans_dic': {},
'nutrition_plans_dic': {},
})
if not cart:
messages.error(request,
"There is nothing in your \
shopping cart at the moment")
return redirect(reverse('products'))
""" Got total from cart_contents """
current_cart = cart_contents(request)
current_total = current_cart['total']
stripe_total = round(current_total * 100)
""" Set secret key on stripe """
stripe.api_key = stripe_secret_key
""" Created payment intent """
intent = stripe.PaymentIntent.create(
amount=stripe_total,
currency=settings.STRIPE_CURRENCY,
)
print(intent)
order_form = OrderForm()
if not stripe_public_key:
messages.warning(request, 'Stripe public key is missing. \
Did you forget to set it in your environment?')
template = 'checkout/checkout.html'
context = {
'order_form': order_form,
'stripe_public_key': stripe_public_key,
'client_secret': intent.client_secret,
}
return render(request, template, context)
If your method == "POST": is true then the intent variable is not assigned any parameter.
context = {
'order_form': order_form,
'stripe_public_key': stripe_public_key,
'client_secret': intent.client_secret,
}
Hence, the intent in last section is not assigned anything.
else:
print("Order form is invalid")
cart = request.session.get('cart', {
'merchandise_dic': {},
'excercise_plans_dic': {},
'nutrition_plans_dic': {},
})
if not cart:
messages.error(request,
"There is nothing in your \
shopping cart at the moment")
return redirect(reverse('products'))
""" Got total from cart_contents """
current_cart = cart_contents(request)
current_total = current_cart['total']
stripe_total = round(current_total * 100)
""" Set secret key on stripe """
stripe.api_key = stripe_secret_key
""" Created payment intent """
---> intent = stripe.PaymentIntent.create(
amount=stripe_total,
currency=settings.STRIPE_CURRENCY,
)
print(intent)
order_form = OrderForm()
intent is assigned inside the else block, but it is referenced outside the else block
context = {
'order_form': order_form,
'stripe_public_key': stripe_public_key,
---> 'client_secret': intent.client_secret,
So if the else block is not executed there is no intent variable.
Thanks every one for your valuable input I found the problem and fixed it. Actually I was not returning anything if the form is valid! Thus I was missing the redirect to checkout_success page at the first for loop level before 1st else.
That is why even if the form is valid it's still trying to return the render() statement at the bottom which was causing this error. Thus I created a checkout_success view and and also checkout_success.html and redirected to it. like this and fixed this error.
return redirect(reverse('checkout_success',
args=[order.order_number]))
Related
I am new to Django and trying to integrate razorpay with my website but getting error
AttributeError: 'str' object has no attribute 'post'
views.py
def order(request, id):
product = Product.objects.get(prod_ID=id)
if request.method == 'POST':
customer_id = request.user
product = Product.objects.get(prod_ID=id)
product_id = product
try:
quantity = request.POST['quantity']
quantity = int(quantity)
order_price = quantity * product.prod_Price
print(order_price)
except MultiValueDictKeyError:
pass
try:
size = request.POST['size']
value.update(size=size)
except MultiValueDictKeyError:
pass
try:
Colour = request.POST['Color']
value.update(Colour=Colour)
except MultiValueDictKeyError:
pass
attribute_value = json.dumps(value)
order_store = Order(user_id=customer_id, prod_id=product_id, quantity=quantity,
attribute_value=attribute_value,
order_price=order_price)
if order_store:
order_store.save()
o_id = Order.objects.get(order_id=order_store.order_id)
payment_store = Payment(order_id=o_id)
payment_store.save()
client = razorpay.Client('rzp_test_Cut6mUJgrjfQU', 'LSNlrKrH0NoUq8Y9rEUbg27')
print(client)
data = {
'amount': order_price * 100,
'currency': "INR",
'receipt': 'Order for ' + str(o_id.order_id),
'notes': {
'name': o_id.user_id.first_name + o_id.user_id.last_name,
'Payment_for': o_id.prod_id.prod_Name
}
}
print(data)
order_detail = client.order.create(data=data)
print(order_detail)
return render(request, 'user/payment.html', {'order_store': order_store})
context = {'products': products
}
return render(request, 'user/order.html', context)
Here I am trying to integrate payment with my website but after creating order and payment status I am trying to do payment but I don't know what I am doing wrong.
To intialize the client you have to use the auth parameter - see razorpay Initialization.
And give a tuple as value:
import razorpay
client = razorpay.Client(auth=("<YOUR_KEY>", "<YOUR_SECRET>"))
i was trying to make my first e-commerce website using django and i received this error.
I already search in google but I can't find how to fix it. please help me to find the error.
this is attached. If any data is missing please comment.
cart.js :
var updateBtns = document.getElementsByClassName('update-cart')
for (var i = 0; i < updateBtns.length; i++) {
updateBtns[i].addEventListener('click', function () {
var productId = this.dataset.product`enter code here`
var action = this.dataset.action
console.log('productId:', productId, 'Action:', action)
console.log('USER:', user)
if (user == 'AnonymousUser') {
console.log('Not logged in')
} else {
updateUserOrder(productId)
}
})
}
function updateUserOrder(productId, action) {
console.log('User is logged in, sending data...')
var url = '/update_item/'
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken,
},
body: JSON.stringify({ 'productId': productId, 'action': action })
})
.then(response => response.json())
.then((data) => {
console.log('data:', data);
}
);
}
views.py :
from django.shortcuts import render
from django.http import JsonResponse
from django.http import HttpRequest
import json
from .models import *
def store(request):
products = Product.objects.all()
context = {'products': products}
return render(request, 'store/store.html', context)
def cart(request):
if request.user.is_authenticated:
customer = request.user.customer
order, created = Order.objects.get_or_create(
customer=customer, complete=False)
items = order.orderitem_set.all()
else:
# Create empty cart for now for non-logged in user
items = []
order = {'get_cart_total': 0, 'get_cart_items': 0}
context = {'items': items, 'order': order}
return render(request, 'store/cart.html', context)
def checkout(request):
if request.user.is_authenticated:
customer = request.user.customer
order, created = Order.objects.get_or_create(
customer=customer, complete=False)
items = order.orderitem_set.all()
else:
# Create empty cart for now for non-logged in user
items = []
order = {'get_cart_total': 0, 'get_cart_items': 0}
context = {'items': items, 'order': order}
return render(request, 'store/checkout.html', context)
def updateItem(request):
data = json.loads(request.data)
productId = data['productId']
action = data['action']
print('Action:', action)
print('productId:', productId)
return JsonResponse('Item was added', safe=False)'''
def updateItem(request):
data = json.loads(request.data)
request.data is available in Django rest framework, but it doesn't exist in regular Django views.
Change the view to use request.body instead.
def updateItem(request):
data = json.loads(request.body)
I am trying to show orders by customer id by i am getting this error :
TypeError at /orders
Field 'id' expected a number but got {'id': 3, 'phone_number': '01622153196', 'email': 'sakibovi#gmail.com', 'password': 'pbkdf2_sha256$216000$H2o5Do81kxI0$2tmMwSnSJHBVBTU9tQ8/tkN7h1ZQpRKrTAKkax1xp2Y=', 'coin': 1200.0}.
Actually i want to fetc only customer id but getting whole dictionary.
Here in Login Class in views.py i fetch whole customers info like this
request.session['customer'] = customer.__dict__
Here is the details :
class Login(View):
def get(self, request):
return render(request, 'signupsignin/signin.html')
def post(self, request):
phone_number = request.POST.get('phone_number')
password = request.POST.get('password')
customer = Customer.get_customer(phone_number)
error_message = None
if customer:
match = check_password(password, customer.password)
if match:
customer.__dict__.pop('_state')
request.session['customer'] = customer.__dict__
# request.session['customer'] = customer.id
#request.session['customer'] = customer.coin
#request.session['phone_number'] = customer.phone_number
return redirect('Home')
else:
error_message = 'Phone number or Password didnt match on our record'
else:
error_message = 'No Customer Found! Please Registrer First!'
print(phone_number, password)
context = {'error_message':error_message}
return render(request, 'signupsignin/signin.html', context)
I think for that reason i am getting the whole informaton of a customer
Here is my Views.py for userorders by customer id ::
class UserOrders(View):
def get(self, request):
customer = request.session.get('customer')
user_orders = Order.get_orders_by_customer(customer)
print(user_orders)
args = {'user_orders':user_orders}
return render(self.request, 'Home/all_orders.html', args)
Here i have a method named get_orders_by_customer() i made this in models.py
Here it is ::
#staticmethod
def get_orders_by_customer(customer__id):
return Order.objects.filter(customer=customer__id)
So what i am trying to do is customers can see their own orders.I have a panel called "all orders" here a customer can see their own order only.
Please Help me i got really confused here
As per my understanding, you have to pass a number, but you're passing a whole dictionary.
#staticmethod
def get_orders_by_customer(customer__id):
return Order.objects.filter(customer=customer__id)
here before return try to debug with a print or something. and you'll see what I mean.
try this and it should work, if im not wrong:
costomer__id['id'] instead of costomer__id
or change your code into this:
#staticmethod
def get_orders_by_customer(customer):
return Order.objects.filter(customer=customer['id'])
You can try using values() query to achieve your purpose.
Here is the link to the documentation - https://docs.djangoproject.com/en/3.1/ref/models/querysets/#values
I am tracking the total cost of items in a shopping cart with Django. My problem is the first item is tracked. When you deduct quantity or reduce quantity the price adjust. But anything that is below it does NOT adjust the total cost. I think the problem is I am not looping through it incorrectly so after many hours of failure I figured I would ask.
In
def cart()
I am looping through the member variables add updating
their values. The problem I am facing is that only the book_id is being passed to the cart() function when you click remove_from_cart
But if it was a problem of only one book_id being passed in then how come only the first item in the cart list is being changed regardless of the book_id that is being passed in?
views.py
#login_required
def add_to_cart(request,book_id):
book = get_object_or_404(Book, pk=book_id)
cart,created = Cart.objects.get_or_create(user=request.user, active=True)
order,created = BookOrder.objects.get_or_create(book=book,cart=cart)
order.quantity += 1
order.save()
messages.success(request, "Cart updated!")
return redirect('cart')
def remove_from_cart(request, book_id):
if request.user.is_authenticated():
try:
book = Book.objects.get(pk = book_id)
except ObjectDoesNotExist:
pass
else:
cart = Cart.objects.get(user = request.user, active = True)
cart.remove_from_cart(book_id)
return redirect('cart')
else:
return redirect('index')
def cart(request):
if request.user.is_authenticated():
cart = Cart.objects.filter(user=request.user.id, active = True)
orders = BookOrder.objects.filter(cart=cart)
total = 0
count = 0
for order in orders:
total += order.book.price * order.quantity
count += order.quantity
context = {
'cart': orders,
'total': total,
'count': count,
}
return render(request, 'store/cart.html', context)
else:
return redirect('index')
Your indentation is slightly off
def cart(request):
if request.user.is_authenticated():
cart = Cart.objects.filter(user=request.user.id, active = True)
orders = BookOrder.objects.filter(cart=cart)
total = 0
count = 0
for order in orders:
total += order.book.price * order.quantity
count += order.quantity
#Indentation needs to be offset by one level from here on
context = {
'cart': orders,
'total': total,
'count': count,
}
return render(request, 'store/cart.html', context)
else:
return redirect('index')
I have a Django program that was developed in Notepad++ but now I have installed Pydev for Eclipse, so , I want to develop the program in Eclipse going forward.
I have cart.py and views.py module under the cart folder but when I import the cart module in views.py file, I get a error--Unresolved import:cart ---on the views.py file import statement..Any help would be appreciated.
cart.py
from cart.models import CartItem
from catalog.models import Product
from django.shortcuts import get_object_or_404
from django.http import HttpResponseRedirect
import decimal
import random
CART_ID_SESSION_KEY = 'cart_id'
#get the current users cart id,set new one if blank
def _cart_id(request):
print 'Get Cart Id'
if request.session.get(CART_ID_SESSION_KEY,'') == '':
print 'Failing here start'
request.session[CART_ID_SESSION_KEY] = _generate_cart_id()
print 'Failing here End'
return request.session[CART_ID_SESSION_KEY]
#
def _generate_cart_id():
print 'Generate cart id'
cart_id = ''
characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!##$%^&*()'
cart_id_length = 50
for y in range(cart_id_length):
cart_id += characters[random.randint(0,len(characters)-1)]
return cart_id
#return all items form the current users cart
def get_cart_items(request):
return CartItem.objects.filter(cart_id =_cart_id(request))
#add an item to the cart
def add_to_cart(request):
postdata = request.POST.copy()
#get product slug from post.data, return blank if empty
product_slug = postdata.get('product_slug','')
#get quantity added,return 1 if empty
quantity = postdata.get('quantity',1)
#fetch the product or return a missing page error
p = get_object_or_404(Product, slug=product_slug)
#get producsts in cart
cart_products = get_cart_items(request)
#check to see if the item is already in cart
product_in_cart = False
for cart_item in cart_products:
if cart_item.product.id == p.id:
cart_item.augment_quantity(quantity)
product_in_cart = True
if not product_in_cart:
ci = CartItem()
ci.product = p
ci.quantity = quantity
ci.cart_id = _cart_id(request)
ci.save()
def cart_distinct_item_count(request):
return get_cart_items(request).count()
views.py
import decimal
from django.shortcuts import render_to_response
from django.template import RequestContext
from ..cart import cart
from django.shortcuts import get_object_or_404
def show_cart(request, template_name="cart/cart.html"):
if request.method == 'POST':
postdata = request.POST.copy()
if postdata['submit'] == 'Remove':
cart.remove_from_cart(request)
if postdata['submit'] == 'Update':
cart.update_cart(request)
cart_items = cart.get_cart_items(request)
page_title = 'Shopping Cart'
cart_subtotal = cart.cart_subtotal(request)
return render_to_response(template_name, locals(),
context_instance=RequestContext(request))
def get_single_item(request, item_id):
return get_object_or_404(CartItem, id=item_id, cart_id=_cart_id(request))
# update quantity for single item
def update_cart(request):
postdata = request.POST.copy()
item_id = postdata['item_id']
quantity = postdata['quantity']
cart_item = get_single_item(request, item_id)
if cart_item:
if int(quantity) > 0:
cart_item.quantity = int(quantity)
cart_item.save()
else:
remove_from_cart(request)
# remove a single item from cart
def remove_from_cart(request):
postdata = request.POST.copy()
item_id = postdata['item_id']
cart_item = get_single_item(request, item_id)
if cart_item:
cart_item.delete()
# gets the total cost for the current cart
def cart_subtotal(request):
cart_total = decimal.Decimal('0.00')
cart_products = get_cart_items(request)
for cart_item in cart_products:
cart_total += cart_item.product.price * cart_item.quantity
return cart_total
The .. in front of from ..cart import cart is probably messing with you.
This means cart.py should be one level up directory-wise than views.py, which from your question derived - is not the case.