示例#1
0
def get_context_data(context, request, category, product_filters):
    data = request.GET
    context["form"] = form = ProductListForm(
        request=request, shop=request.shop, category=category, data=data)
    form.full_clean()
    data = form.cleaned_data
    if "sort" in form.fields and not data.get("sort"):
        # Use first choice by default
        data["sort"] = form.fields["sort"].widget.choices[0][0]

    # TODO: Check if context cache can be utilized here
    products = Product.objects.listed(
        customer=request.customer,
        shop=request.shop
    ).filter(
        **product_filters
    ).filter(get_query_filters(request, category, data=data))

    products = get_product_queryset(products, request, category, data).distinct()
    products = post_filter_products(request, category, products, data)
    products = cache_product_things(request, products)
    products = sort_products(request, category, products, data)
    context["page_size"] = data.get("limit", 12)
    context["products"] = products

    if "supplier" in data:
        context["supplier"] = data.get("supplier")

    return context
示例#2
0
def get_products_for_categories(context, categories, n_products=6, orderable_only=True):
    request = context["request"]
    key, products = context_cache.get_cached_value(
        identifier="products_for_category",
        item=cache_utils.get_products_for_category_cache_item(request.shop),
        context=request,
        n_products=n_products,
        categories=categories,
        orderable_only=orderable_only
    )
    if products is not None:
        return products

    products = _get_listed_products(
        context,
        n_products,
        ordering="?",
        filter_dict={
            "variation_parent": None,
            "shop_products__categories__in": categories
        },
        orderable_only=orderable_only
    )
    products = cache_product_things(request, products)
    context_cache.set_cached_value(key, products, settings.E-Commerce_TEMPLATE_HELPERS_CACHE_DURATION)
    return products
示例#3
0
def get_listed_products(context, n_products, ordering=None, filter_dict=None, orderable_only=True, extra_filters=None):
    """
    A cached version of _get_listed_products
    """
    request = context["request"]

    key, products = context_cache.get_cached_value(
        identifier="listed_products",
        item=cache_utils.get_listed_products_cache_item(request.shop),
        context=request,
        n_products=n_products,
        ordering=ordering,
        filter_dict=filter_dict,
        orderable_only=orderable_only,
        extra_filters=hash(str(extra_filters))
    )
    if products is not None:
        return products

    products = _get_listed_products(
        context,
        n_products,
        ordering=ordering,
        filter_dict=filter_dict,
        orderable_only=orderable_only,
        extra_filters=extra_filters
    )
    products = cache_product_things(request, products)
    context_cache.set_cached_value(key, products, settings.E-Commerce_TEMPLATE_HELPERS_CACHE_DURATION)
    return products
示例#4
0
def _get_best_selling_products(cutoff_days, n_products, orderable_only, request):  # noqa (C901)
    data = get_best_selling_product_info(
        shop_ids=[request.shop.pk],
        cutoff_days=cutoff_days
    )
    combined_variation_products = defaultdict(int)
    for product_id, parent_id, qty in data:
        if parent_id:
            combined_variation_products[parent_id] += qty
        else:
            combined_variation_products[product_id] += qty

    # get all the product ids
    product_ids = [
        d[0] for
        d in sorted(six.iteritems(combined_variation_products), key=lambda i: i[1], reverse=True)
    ]

    # group product ids in groups of n_products
    # to prevent querying ALL products at once
    products = []
    for grouped_product_ids in _group_list_items(product_ids, n_products):
        valid_products_qs = Product.objects.listed(
            shop=request.shop,
            customer=request.customer
        ).filter(
            id__in=grouped_product_ids,
            shop_products__shop=request.shop,
            shop_products__suppliers__enabled=True
        )
        for product in valid_products_qs.iterator():
            products.append(product)

            if len(products) == n_products:
                break

        if len(products) == n_products:
            break

    if orderable_only:
        valid_products = []
        suppliers = Supplier.objects.enabled().filter(shops=request.shop)

        for product in products:
            # this instance should always exist as the listed() queryset uses the current shop as a filter
            shop_product = product.get_shop_instance(request.shop, allow_cache=True)

            for supplier in suppliers:
                if shop_product.is_orderable(supplier, request.customer, shop_product.minimum_purchase_quantity):
                    valid_products.append(product)
                    break

        products = valid_products

    products = cache_product_things(request, products)
    products = sorted(products, key=lambda p: product_ids.index(p.id))  # pragma: no branch
    return products
示例#5
0
 def get_context_data(self, **kwargs):
     context = super(SearchView, self).get_context_data(**kwargs)
     context["form"] = self.form
     products = context["products"]
     if products:
         data = self.form.cleaned_data
         products = post_filter_products(self.request, None, products, data)
         products = cache_product_things(self.request, products)
         products = sort_products(self.request, None, products, data)
         products = [p for p in products if is_visible({"request": self.request}, p)]
         context["products"] = products
     context["no_results"] = (self.form.is_valid() and not products)
     return context
示例#6
0
def get_product_context(request, product, language=None, supplier=None):   # noqa (C901)
    """
    Get product context

    Used in `E-Commerce.front.views.product:ProductDetailView`

    :return: A context dict containing everything needed to render product view
    :rtype: dict
    """
    if not language:
        language = get_language()

    shop_product = product.get_shop_instance(request.shop)
    context = {}
    context["product"] = product
    context["category"] = shop_product.primary_category
    context["orderability_errors"] = list(shop_product.get_orderability_errors(
        supplier=supplier, quantity=1, customer=request.customer, ignore_minimum=True))
    context["variation_children"] = []

    selected_variation = None
    variation_sku = request.GET.get("variation")
    if variation_sku:
        try:
            selected_variation = product.variation_children.get(sku=variation_sku)
            context["selected_variation"] = selected_variation
        except Product.DoesNotExist:
            raise Http404

    if product.mode == ProductMode.SIMPLE_VARIATION_PARENT:
        context["variation_children"] = cache_product_things(
            request,
            sorted(
                product.variation_children.language(language).visible(
                    shop=request.shop, customer=request.customer
                ),
                key=lambda p: get_string_sort_order(p.variation_name or p.name)
            )
        )
        context["orderable_variation_children"] = []
        for p in context["variation_children"]:
            try:
                if p.get_shop_instance(request.shop).is_orderable(
                        supplier=supplier, customer=request.customer, quantity=1):
                    context["orderable_variation_children"].append(p)
            except ShopProduct.DoesNotExist:
                pass

    elif product.mode == ProductMode.VARIABLE_VARIATION_PARENT:
        variation_variables = product.variation_variables.all().prefetch_related("values")
        orderable_children, is_orderable = get_orderable_variation_children(
            product, request, variation_variables, supplier
        )
        context["orderable_variation_children"] = orderable_children
        context["variation_orderable"] = is_orderable
        context["variation_variables"] = variation_variables

        if selected_variation:
            for combination in product.get_all_available_combinations():
                if combination['result_product_pk'] == selected_variation.pk:
                    values = [v.pk for v in combination['variable_to_value'].values()]
                    context['selected_variation_values'] = values
                    break
    elif product.is_container():
        children = product.get_all_package_children().translated().order_by("translations__name")
        context["package_children"] = cache_product_things(request, children)

    context["shop_product"] = shop_product
    context["attributes"] = product.attributes.filter(
        attribute__visibility_mode=AttributeVisibility.SHOW_ON_PRODUCT_PAGE)
    context["primary_image"] = shop_product.public_primary_image
    context["images"] = shop_product.public_images
    context["supplier"] = supplier
    context["order_form"] = _get_order_form(request, context, product, language)

    for provide_object in get_provide_objects("product_context_extra"):
        provider = provide_object(request, product, language)
        if provider.provides_extra_context():
            context.update(provider.extra_context)

    return context