@register.inclusion_tag('lfs/catalog/product_navigation.html', takes_context=True)
def product_navigation(context, product):
    """Provides previous and next product links.
    """
    request = context.get("request")

    try:
        default_sorting = settings.LFS_PRODUCTS_SORTING
    except AttributeError:
        default_sorting = "effective_price"
    sorting = request.session.get("sorting", default_sorting)
    if sorting.strip() == '':
        sorting = 'effective_price'
        request.session["sorting"] = sorting

    slug = product.slug

    # To calculate the position we take only STANDARD_PRODUCT into account.
    # That means if the current product is a VARIANT we switch to its parent
    # product.
    if product.is_variant():
        product = product.parent
        slug = product.slug

    # prepare cache key for product_navigation group
    # used to invalidate cache for all product_navigations at once
    pn_cache_key = get_cache_group_id('product_navigation')

    # if there is last_manufacturer then product was visited from manufacturer view
    # as category view removes last_manufacturer from the session
    lm = request.session.get('last_manufacturer')
    if lm and product.manufacturer == lm:
        cache_key = "%s-%s-product-navigation-manufacturer-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX,
                                                                  pn_cache_key,
                                                                  slug)
        res = cache.get(cache_key)
        if res and sorting in res:
            return res[sorting]

        products = Product.objects.filter(manufacturer=lm)
    else:
        category = product.get_current_category(request)
        if category is None:
            return {"display": False}
        else:
            cache_key = "%s-%s-product-navigation-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX,
                                                         pn_cache_key,
                                                         slug)
            res = cache.get(cache_key)
            if res and sorting in res:
                return res[sorting]

            # First we collect all sub categories. This and using the in operator makes
            # batching more easier
            categories = [category]

            if category.show_all_products:
                categories.extend(category.get_all_children())

            products = Product.objects.filter(categories__in=categories)

    # This is necessary as we display non active products to superusers.
    # So we have to take care for the product navigation too.
    if not request.user.is_superuser:
        products = products.filter(active=True)
    products = products.exclude(sub_type=VARIANT).distinct().order_by(sorting)

    product_slugs = list(products.values_list('slug', flat=True))
    product_index = product_slugs.index(slug)

    if product_index > 0:
        previous = product_slugs[product_index - 1]
    else:
        previous = None

    total = len(product_slugs)
    if product_index < total - 1:
        next_product = product_slugs[product_index + 1]
    else:
        next_product = None

    result = {
        "display": True,
        "previous": previous,
        "next": next_product,
        "current": product_index + 1,
        "total": total,
        "STATIC_URL": context.get("STATIC_URL"),
    }

    cache.set(cache_key, {'sorting': result})

    return result
dataset/ETHPy150Open diefenbach/django-lfs/lfs/core/templatetags/lfs_tags.py/product_navigation/original