basket = Basket.objects.filter(user=request.user, book=book).first()
if not basket:
basket = Basket(user=request.user, book=book)
basket.quantity += 1
basket.save()
from collections import UserDict
from core.models import ProductOption, Product
from .models import Item
class Basket(UserDict):
changed = False
def add(self, quantity=0, option=None, set_=False):
self.changed = True
id_ = str(option.product.id)
option = str(option.id)
self.setdefault(id_, {})
self[id_].setdefault(option, 0)
if set_:
self[id_][option] = quantity
else:
self[id_][option] += quantity
if self[id_][option] <= 0:
del self[id_][option]
if not self[id_]:
del self[id_]
return 0
else:
return self[id_][option]
@property
def total_count(self):
return sum(x for product, options in self.items() for _, x in options.items())
@property
def total_price(self):
prices = {str(id_): price for id_, price in
Product.objects.filter(id__in=self.keys()).values_list('id', 'price')}
return sum(x * prices[product] for product, options in self.items() for _, x in options.items())
def cost(self, option):
price = option.product.price
return self.count_option(option) * price
def count_option(self, option):
product_id = str(option.product.id)
option_id = str(option.id)
return self.get(product_id, {}).get(option_id, 0)
def flush(self):
self.changed = True
for key in list(self):
del self[key]
def build_order(self, order):
items = []
for product_id, data in self.items():
product = Product.objects.get(id=product_id)
for option_id, quantity in data.items():
if quantity == 0:
continue
option = None
if option_id != '0':
option = ProductOption.objects.get(id=option_id)
items.append(
Item(order=order, option=option, quantity=quantity, product=product)
)
order.items.bulk_create(items)
self.flush()
return order
def fix(self):
"""Фиксит корзину на случай, если опции удалили, а они находятся в корзине"""
ids = self.keys()
exist_in_db = (Product.objects
.filter(id__in=ids, options__in_stock=True, options__show=True)
.values_list('id', flat=True))
to_remove = set(ids) - set(str(x) for x in exist_in_db)
for id_ in to_remove:
del self[id_]
if to_remove:
self.changed = True
def to_dict(self):
return dict(self)
from django.utils.deprecation import MiddlewareMixin
from .basket import Basket
class BasketMiddleware(MiddlewareMixin):
def process_request(self, request):
request.basket = Basket(request.session.get('basket', {}))
def process_response(self, request, response):
if getattr(request, 'basket', None) is None:
return response
if request.basket.changed:
request.session['basket'] = request.basket.to_dict()
request.session.save()
return response
# ...
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
MIDDLEWARE_CLASSES = [
# ...
'orders.middleware.BasketMiddleware',
]
# ...
@method_decorator(csrf_exempt, name='dispatch')
class ChangeBasketOption(View):
def post(self, request):
change = int(request.POST.get('change'))
pk = int(request.POST.get('id'))
set_ = bool(request.POST.get('set', 0))
option = get_object_or_404(ProductOption, pk=pk)
value = request.basket.add(option=option, quantity=change, set_=set_)
cost = request.basket.cost(option)
return JsonResponse({
'value': value,
'cost': cost,
'total': request.basket.total_price
})
class Basket(FormView):
template_name = 'orders/basket.html'
form_class = OrderForm
success_url = reverse_lazy('ordered')
def get(self, request, *args, **kwargs):
request.basket.fix()
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
kwargs['products'] = Product.objects.filter(id__in=self.request.basket.keys())
kwargs['can_order'] = self.request.basket.total_price >= min_order_cost()
return super().get_context_data(**kwargs)
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
def form_valid(self, form):
order = form.save()
order = self.request.basket.build_order(order)
mail_new_order(order)
return super().form_valid(form)
for(i=0; i<1000; i++)
i=INT_MAX;
void main() {
// ...
void init_dialog(); init_dialog();
void init_referenceControl(); init_referenceControl();
void init_functionsHelp(); init_functionsHelp();
void init_new_style(); init_new_style();
// ...
}
</souce>
Вместо определения функций в .H файлах, я это сделал прямо на месте. Говнокод. Можно было бы создать кучу .H файлов, использовать одну из множества библиотек выполняющих инициализацию. Но это максимально простой способ, способ без использования доп классов, функций и программ; так легче отлаживать, так наглядно изображена последовательность инициализации, так не надо писать кучу #include, и кроме функции MAIN, функции инициализации ни от куда не вызвать.
Говнокод - потому что люди бы не так написали.