Очистите корзину покупок в приложении Django, сохраняя ее в сеансе с задачей сельдереяPython

Программы на Python
Ответить
Anonymous
 Очистите корзину покупок в приложении Django, сохраняя ее в сеансе с задачей сельдерея

Сообщение Anonymous »

Здравствуйте, я пытаюсь создать приложение для электронной коммерции с помощью Django. У меня есть класс корзины покупок, который работает с сеансом, это мой класс корзины:

Код: Выделить всё

from django.conf import settings
from shop.models import Product, ProductColor
from django.shortcuts import get_object_or_404
from django.utils import timezone

class Cart:
def __init__(self, request_or_session_data):
if hasattr(request_or_session_data, 'session'):  # Check if it's a request
self.session = request_or_session_data.session
else:
# If it's session data, use it directly
self.session = request_or_session_data
cart = self.session.get(settings.CART_SESSION_ID)
if not cart:
cart = self.session[settings.CART_SESSION_ID] = {}
self.cart = cart
self.total_discount = None
self.discount_code = None
self.have_discount_code = self.session.get("have_discount_code", False)
self.discount_code_amount = self.session.get("discount_code_amount", 0)
self.last_updated = self.session.get("last_updated")
if hasattr(request_or_session_data, 'user') and request_or_session_data.user.is_authenticated:
self.user = request_or_session_data.user

def add(self, product, color_id, quantity=1, override_quantity=False):
product_id = str(product.id)
color = get_object_or_404(ProductColor, id=color_id)
cart_key = f"{product_id}_{color_id}"

if cart_key not in self.cart:
self.cart[cart_key] = {
'color_id': str(color.id),
'quantity': 0,
'price': str(product.price),
'discount': str(product.discount),
'discount_price': str(product.get_discounted_price()),
}

if override_quantity:
self.cart[cart_key]['quantity'] = quantity
else:
self.cart[cart_key]['quantity'] += quantity

self.total_discount = self.get_total_discount()
self.save()

def mark_session_modified(self):
# Mark session as modified if `self.session` is a Django session object
if hasattr(self.session, 'modified'):
self.session.modified = True

def save(self):
# mark the session as "modified"  to make sure it gets saved
self.last_updated = timezone.now()
self.session[settings.CART_SESSION_ID] = self.cart
self.session['have_discount_code'] = self.have_discount_code
self.session['discount_code_amount'] = self.discount_code_amount
self.session['last_updated'] = self.last_updated.isoformat()
if hasattr(self, 'user') and self.user:
self.session["user_id"] = self.user.id
self.mark_session_modified()

def remove(self, product, color_id=None):
product_id = str(product.id)
if color_id:
cart_key = f"{product_id}_{color_id}"
if cart_key in self.cart:
del self.cart[cart_key]
else:
# If no color_id is provided, remove all items related to the product_id
keys_to_remove = [key for key in self.cart if key.startswith(product_id)]
for key in keys_to_remove:
del self.cart[key]

if len(self.cart) == 0:
self.clear()  # Call the clear method to remove discount codes and other data

else:
self.total_discount = self.get_total_discount()  # Update total discount
self.save()

def __iter__(self):
cart = self.cart.copy()
product_ids = {key.split('_')[0] for key in cart.keys()}  # Extract product IDs
products = Product.objects.filter(id__in=product_ids)

for product in products:
for key in cart.keys():
if key.startswith(str(product.id)):
item = cart[key]
item["product"] = product

# Extract color ID from the key
color_id = key.split('_')[1] if '_' in key else None

# Get the corresponding ProductColor instance
if color_id:
try:
product_color = ProductColor.objects.get(id=color_id, product=product)
item["color_name"] = product_color.color  # Use the color from ColorChoices
except ProductColor.DoesNotExist:
item["color_name"] = "Unknown Color"
else:
item["color_name"] = "No Color"

item["color_id"] = str(color_id)
item["product_id"] = str(product.id)
item["price"] = int(item["price"])
item["discount_price"] = int(item["discount_price"])
if item["discount"] == "0":
item["total_price"] = item["price"] * item["quantity"]
else:
item["total_price"] = item["discount_price"] * item["quantity"]

yield item

def __len__(self):
return sum(item['quantity'] for item in self.cart.values())

def get_total_price(self):
total_price = 0
for item in self:
total_price += item["total_price"]
if self.have_discount_code:
discount_factor = self.discount_code_amount / 100
total_price = int(total_price * (1 - discount_factor))
return total_price

def add_coupon(self, amount,  code):
self.discount_code_amount = amount
self.have_discount_code = True
self.discount_code = code
self.save()

def get_total_discount(self):
total_discount = 0
for item in self.cart.values():
if item["discount"] != "0":
discount = int(item["price"]) - int(item["discount_price"])
total_discount += discount * item["quantity"]
return total_discount

@property
def total_get_price_of_discount(self):
total_price = 0
for item in self:
total_price += item["total_price"]
price = self.get_total_price()

return total_price - price

def clear(self):
# remove cart from session
del self.session[settings.CART_SESSION_ID]
self.have_discount_code = False
self.discount_code = None
self.discount_code_amount = 0
self.total_discount = None
self.save()
каждый раз, когда пользователи добавляют товар в корзину, я уменьшаю количество товаров, и у меня есть задача проверить, простаивает ли их корзина более 30 минут, сначала отправьте пользователю SMS и напомните им о корзине покупок, и через 1 час очистите корзину и добавьте количество обратно в продукты. Проблема заключается в том, что в задаче я пытаюсь зациклиться на всех сеансах и изменить этот сеанс с помощью session_data["sms_sent"] = True после этого он снова отправит смс, а когда пройдет более 1 часа, он добавит количество обратно в базу данных, но не очистит корзину из сеанса
это задача, которую я использую:< /p>

Код: Выделить всё

@shared_task
def clear_abandoned_carts():
expired_time = timezone.now() - CART_EXPIRATION_TIME
warning_time = timezone.now() - SEND_WARNING_TIME

for session in Session.objects.filter(expire_date__gte=timezone.now()):
data = session.get_decoded()
last_updated_str = data.get("last_updated")
cart = data.get(settings.CART_SESSION_ID)
print("sms_sent flag before:", data.get("sms_sent"))  # Safe access

if cart and last_updated_str:
last_updated = timezone.datetime.fromisoformat(last_updated_str)

if last_updated < expired_time:
# Clear cart if expired
for key, item in cart.items():
color_id = item["color_id"]
quantity = item["quantity"]
try:
remove_from_cart(color_id, int(quantity))
except ProductColor.DoesNotExist:
pass  # Handle as needed

# Clear session data
session_data = session.get_decoded()
session_data.pop(settings.CART_SESSION_ID, None)
session_data.pop("last_updated", None)
session_data.pop("have_discount_code", None)
session_data.pop("discount_code_amount", None)
session_data.pop("sms_sent", None)
session_data["modified"] = True

session.save()
cart_instance = Cart(data)
cart_instance.clear()

elif last_updated < warning_time:
# Check if the SMS warning was already sent
if not data.get("sms_sent"):  # Proceed only if SMS hasn't been sent
user_id = data.get("user_id")
if user_id:
try:
user = CustomUser.objects.get(id=user_id)
if user.phone_number:
phone_number = user.phone_number
send_cart_warning(int(phone_number))  # Send SMS

# Mark SMS as sent in session data
session_data = session.get_decoded()
session_data["sms_sent"] = True  # Safely update session
session_data["modified"] = True
session.modified = True
session.save()

print("sms_sent flag after:", session_data.get("sms_sent"))  # Safe access

except CustomUser.DoesNotExist:
pass
в консоли, когда оно отправляет сообщение, это print("sms_sent flag after:", session_data.get("sms_sent")) дает мне True, но когда оно запускается снова, это print(" флаг sms_sent перед:", data.get("sms_sent")) дайте мне Нет, ребята, помогите мне решить эту проблему, пожалуйста

Подробнее здесь: https://stackoverflow.com/questions/791 ... clery-task
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»