def fill_seo(self, **kwargs): """Заполнение сео-полей/статей для товара, заполнение привязок к статьям (привязваем контейнеры) просто создаем ссылку с сео-полями по ссылке товара, """ if not self.id: return seo_fields = ('seo_title', 'seo_description', 'seo_keywords') linkcontainer = kwargs.get('linkcontainer', []) seo_block = None seo_tag = 'seo_for_products' product_tag = 'product_%s' % self.id link = self.link() seo_container = Containers.objects.filter(state=4, tag=seo_tag).first() if not seo_container: seo_container = Containers.objects.create( state=4, tag=seo_tag, name='Сео-тексты для товаров/услуг') seo_blocks = seo_container.blocks_set.filter( models.Q(tag=product_tag) | models.Q(link=link)) # Если по id не найден блок, # тогда пробуем найти по ссылке if not seo_blocks: seo_block = Blocks( state=4, container=seo_container, tag=product_tag, link=link, ) else: for block in seo_blocks: if block.tag == product_tag: seo_block = block break if not seo_block: seo_block = seo_blocks[0] seo_block.link = link seo_block.name = self.name for key in seo_fields: field = key.replace('seo_', '') setattr(seo_block, field, kwargs.get(key)) seo_block.save() link_containers2block(seo_block, linkcontainer)
def get_cat_for_site(request, link: str = None, with_props: bool = True, with_filters: bool = True, **kwargs): """Для ображения каталога на сайте по link :param link: ссылка на рубрику (без /cat/ префикса) :param with_props: Вытащить свойства товаров :param with_filters: Вытащить свойства для фильтров, например, максимальная и минимальная цена """ cat_type = get_ftype('flatcat', False) page = Blocks(name='Каталог') containers = {} catalogue = None breadcrumbs = [] q_string = kwargs.get('q_string', {}) is_search = False search_terms = [] if not link: link = '/cat/' else: link = '/cat/%s' % link if not link.endswith('/'): link = '%s/' % link q_string_fill(request, q_string) # Поиск альтернативных каталогов tag = settings.DEFAULT_CATALOGUE_TAG catalogue_tag, is_root_level = search_alt_catalogue(link) if catalogue_tag: tag = catalogue_tag if link == '/cat/' or is_root_level: is_root_level = True # Поиск всегда идет на /cat/ q = q_string['q'].get('q') catalogue = Containers.objects.filter(tag=tag, state=cat_type).first() if not catalogue: catalogue = create_new_cat() page.name = catalogue.name page.link = link if q: page.name = 'Вы искали %s' % q ids_products, search_terms = search_products(q) is_search = True query = Products.objects.filter(pk__in=ids_products) else: query = ProductsCats.objects.filter(product__isnull=False, container=catalogue) else: page = Blocks.objects.select_related('container').filter( link=link, container__state=cat_type).first() if page: catalogue = page.container query = ProductsCats.objects.filter(cat__container=catalogue, product__is_active=True) if not catalogue: return { 'page': page, 'q_string': q_string, 'breadcrumbs': breadcrumbs, 'error': 404, } if not is_root_level: breadcrumbs.append({ 'name': catalogue.name, 'link': catalogue.cat_link() }) page_parents = page.parents if page.parents else '' cond = Q() cond.add(Q(cat=page), Q.OR) cond.add(Q(cat__parents='%s_%s' % (page_parents, page.id)), Q.OR) cond.add( Q(cat__parents__startswith='%s_%s_' % (page_parents, page.id)), Q.OR) # Выбираем только активные pk_arr = ProductsCats.objects.filter( cond, cat__is_active=True).values_list('id', flat=True) pk_arr = list(pk_arr) # чтобы в subquery не уходило query = query.filter(pk__in=pk_arr, product__is_active=True) if page.parents: ids_parents = [ int(parent) for parent in page.parents.split('_') if parent ] parents = {} search_parents = Blocks.objects.filter(pk__in=ids_parents) for parent in search_parents: parents[parent.id] = parent for item in ids_parents: parent = parents[item] breadcrumbs.append({'name': parent.name, 'link': parent.link}) prefix = 'product__' if is_search: prefix = '' # ----------------------------- # Фильтрация ProductsProperties # В рамках одного свойства # надо фильтровать по ИЛИ, не И # ----------------------------- facet_filters = get_facet_filters(request) if facet_filters: query = query.filter( **{'%sid__in' % (prefix, ): facet_filters['ids_products']}) breadcrumbs.append({'name': page.name, 'link': page.link}) total_records = query.aggregate(Count('id'))['id__count'] # Сортировка sort = request.GET.get('sort') if sort == 'price': query = query.order_by('%smin_price' % prefix) q_string['q']['sort'] = 'price' q_string['sort_name_filter'] = 'Цена по возрастанию' elif sort == '-price': query = query.order_by('-%smax_price' % prefix) q_string['q']['sort'] = '-price' q_string['sort_name_filter'] = 'Цена по убыванию' else: # По умолчанию сортировка по позиции query = query.order_by('%sposition' % prefix) paginator_template = 'web/paginator.html' my_paginator, records = myPaginator(total_records, q_string['page'], q_string['by']) paginator = navigator(my_paginator, q_string, paginator_template) # Фильтры по свойствам # Фильтр по цене, но только если не сильно много товаров # в противном случае это аяксом надо делать cost_filter = None if with_filters and total_records < FAT_HIER: costs = query.aggregate(Max('%sprice' % prefix), Min('%sprice' % prefix)) cost_filter = { 'min': costs['%sprice__min' % prefix], 'max': costs['%sprice__max' % prefix], } if is_search: products = query[records['start']:records['end']] breadcrumbs.append({ 'name': 'Вы искали %s' % q, 'link': '%s?q=%s' % (page.link, q) }) else: query = query.select_related('product') cat_products = query[records['start']:records['end']] products = [product.product for product in cat_products] if with_props: get_props_for_products(products) get_costs_types(products) # TODO: кэшировать по ссылке return { 'page': page, 'q_string': q_string, 'breadcrumbs': breadcrumbs, 'catalogue': catalogue, 'paginator': paginator, 'my_paginator': my_paginator, 'products': products, 'cost_filter': cost_filter, 'search_terms': search_terms, 'facet_filters': facet_filters.get('facet_filters'), }