from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage from django.shortcuts import get_object_or_404, redirect from django.views.generic import * from .models import * from store.cart import Cart, CartItem from django.contrib import messages class CategoryBaseView(object): category = None def _get_full_category(self, categories_string): cats = categories_string.split('/') category = get_object_or_404(Category, slug=cats[0]) for c in cats: if c != category.slug: category = get_object_or_404(category.childs, slug=c) return category class CategoryView(CategoryBaseView, TemplateView): template_name = 'category.jinja' brand_pks = [] products_qs = None sort = None ORDER_PARAMETERS = ( ('date', 'pk'), ('-date', '-pk'), ('price', 'price_min'), ('-price', '-price_min'), ) def _get_brand_pks(self): brand_pks = [] for v in self.request.GET.getlist('brand[]'): try: brand_pks.append(int(v)) except: pass return brand_pks def _get_sort(self): sort = self.request.GET.get('sort', None) return sort def paginate(self): paginate_by = self.request.GET.get('paginate_by', 10) if paginate_by == 'all': paginate_by = 10000 paginator = Paginator(self.products_qs, int(paginate_by)) page = self.request.GET.get('page') try: self.products_qs = paginator.page(page) except PageNotAnInteger: self.products_qs = paginator.page(1) except EmptyPage: self.products_qs = paginator.page(paginator.num_pages) def _get_filter_attributes(self): for k in self.request.GET: attr = Attribute.objects.filter(slug=k.replace('[]', '')) if attr: attr_values = self.request.GET.getlist(k) while 'false' in attr_values: attr_values.remove('false') attr_values = [v.strip() for v in attr_values] if attr_values: self.products_qs = self.products_qs.filter( product_attributes__attribute__attribute__in=attr, product_attributes__value__in=attr_values).distinct() def get_context_data(self, **kwargs): retval = super(CategoryView, self).get_context_data() self.category = self._get_full_category(kwargs['categories']) self.products_qs = self.category.get_all_products().order_by('-pk') self.brand_pks = self._get_brand_pks() self.sort = self._get_sort() if self.brand_pks: self.products_qs = self.products_qs.filter( brand__pk__in=self.brand_pks) if self.sort: sort_parameter = dict(self.ORDER_PARAMETERS)[self.sort] preordered_qs = self.products_qs if sort_parameter in ['price_min', '-price_min']: preordered_qs = self.products_qs.extra( select={ 'price_min': 'SELECT MIN(price) FROM store_productvariation ' + 'WHERE store_productvariation.product_id ' + '= store_product.id' }) self.products_qs = preordered_qs.order_by(sort_parameter) self._get_filter_attributes() self.paginate() retval['category'] = self.category retval['products'] = self.products_qs return retval class ProductView(CategoryBaseView, DetailView): model = Product template_name = 'product.jinja' def get(self, request, *args, **kwargs): self.category = self._get_full_category(kwargs['categories']) retval = super(ProductView, self).get(request, args, kwargs) return retval def get_context_data(self, **kwargs): retval = super(ProductView, self).get_context_data() retval['category'] = self.category return retval class CartAddView(RedirectView): def dispatch(self, request, *args, **kwargs): retval = super(CartAddView, self).dispatch(request, args, kwargs) cart = Cart(self.request) item_variant = ProductVariation.objects.get( pk=self.request.GET.get('pk')) count = self.request.GET.get('count') messages.success( self.request, """Товар успешно добавлен в корзину! Вы можете перейти к оформлению заказа, либо продолжить выбор товаров. Открыть корзину...""") cart.add_item(CartItem(item_variant, count)) return retval def get_redirect_url(self, *args, **kwargs): return self.request.GET.get('next', '/') class CartRemoveView(RedirectView): def dispatch(self, request, *args, **kwargs): retval = super(CartRemoveView, self).dispatch(request, args, kwargs) cart = Cart(self.request) item_id = self.request.GET.get('id') cart.remove_item(item_id) return retval def get_redirect_url(self, *args, **kwargs): return '/store/cart/' class CartDetailView(TemplateView): template_name = 'cart_detail.jinja' def get_context_data(self, **kwargs): retval = super(CartDetailView, self).get_context_data() retval['cart'] = Cart(self.request) return retval def post(self, request, *args, **kwargs): cart = Cart(self.request) cart.update_items() return redirect(self.request.path)