Как я могу избежать дублирования параметров набора запросов URL?

#django-queryset #django-urls

#django-queryset #django-urls

Вопрос:

В приведенном ниже коде наборы запросов предназначены для фильтрации / сортировки моих продуктов, и они работают. Как вы можете видеть, если я хочу отфильтровать уже отфильтрованные продукты, я просто добавляю к нему другой URL-адрес набора запросов. Проблема в том, как выглядит дублированный код. Есть ли другой способ обойти?

Пример того, как выглядит страница и работает URL

ProductsListView views.py

 class ProductsListView(ListView):
    model = Product
    template_name = 'products_list.html'
    context_object_name = 'products'

    def get_queryset(self):
        products = Product.objects.all()

        # SORT BY PRICE
        price = self.request.GET.get('price', None)

        if price == 'desc':
            products = products.order_by('-price')

        if price == 'asc':
            products = products.order_by('price')

        # -- SORT BY PRICE END --

        # SORT BY BRAND
        brand = self.request.GET.get('brand', None)

        if brand is not None:
            products = products.filter(brand__iexact=brand)

        # -- SORT BY BRAND END --

        # SORT BY SEARCH
        search = self.request.GET.get('search', None)

        if search is not None:
            products = products.filter(name__icontains=search)

        # -- SORT BY SEARCH END --

        # -- SORT BY CATEGORY
        category_id = self.request.GET.get('category', None)

        if category_id is not None:
            products = products.filter(category__id=int(category_id))

        # -- SORT BY CATEGORY END --

        return products

    def get_context_data(self, **kwargs):
        context = super().get_context_data()

        # CATEGORIES
        categories = Category.objects.all()
        context['categories'] = categories
        # --

        # CATEGORY NAME
        category_id = self.request.GET.get('category', None)

        try:
            category_name = Category.objects.get(pk=category_id)
        except ObjectDoesNotExist:
            category_name = None

        context['category_name'] = category_name
        # --

        brand_name = self.request.GET.get('brand')
        context['brand_name'] = brand_name

        price_sort_type = self.request.GET.get('price')
        context['price_sort_type'] = price_sort_type
        # CATEGORY PRODUCTS
        # Filtering products by category if in a category
        if category_name is not None:
            category_products = Product.objects.filter(category__id=category_id)
        else:
            category_products = Product.objects.all()
        context['category_products'] = category_products
        # --

        return context
 

Шаблон списка продуктов

 <ul class="list-group">
                <li class="list-group-item mr-3">
                    <a class="dropdown-toggle text-dark" data-toggle="dropdown" href="#">
                        Brand
                    </a>
                    <ul class="dropdown-menu" role="menu" aria-labelledby="BrandDropDown">
                        {% for p in category_products %}

                            {% if category_name and price_sort_type %}
                                <li><a class="dropdown-item" href="{% url 'products' %}?category={{p.category.id}}amp;price={{price_sort_type}}amp;brand={{p.brand | urlencode}}">{{p.brand}}</a></li>

                            {% elif category_name %}
                                <li><a class="dropdown-item" href="{% url 'products' %}?category={{p.category.id}}amp;brand={{p.brand | urlencode}}">{{p.brand}}</a></li>

                            {% elif brand_name %}
                                <li><a class="dropdown-item" href="{% url 'products' %}?brand={{p.brand}}amp;price={{price_sort_type}}">{{p.brand}}</a></li>

                            {% else %}
                                <li><a class="dropdown-item" href="{% url 'products' %}?brand={{p.brand}}">{{p.brand}}</a></li>
                            {% endif %}

                        {% endfor %}
                    </ul>
                </li>
            </ul>