Пример #1
0
    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)
Пример #2
0
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'),
    }