V
V
Vova2018-09-02 19:11:43
Django
Vova, 2018-09-02 19:11:43

QuerySet output given 2 factors?

Basically, I'm new to Django. To the point .. There is a site (online store), on the main page of which there are, let's say, goods. They can be sorted into categories. Also on the main page there is pagination (Pagination). In order not to load the browser, 9 products should be displayed at a time. Question: How to set up pagination correctly to take into account the Product Category, how to get

products

I threw about
view.py

def productlist(request, category_slug=None):
    category = None
    categories = Category.objects.all()
    products = Product.objects.filter(available=True)
    paginator = Paginator(products, 6)
    page = request.GET.get('page')
    template = 'shop/product/list.html'
    if category_slug:
        category = get_object_or_404(Category, slug=category_slug)
        products = products.filter(category=category)
    try:
        products = paginator.page(page)
    except PageNotAnInteger:
        products = paginator.page(1)
    except EmptyPage:
        products = paginator.page(paginator.num_pages)
    context = {
        'category': category,
        'categories': categories,
        'products': products,
        'page': page
    }
    return render(request, template, context)

And here is the model
class Product(models.Model):
    category = models.ForeignKey(
        Category,
        related_name='products',
        verbose_name='Категорія'
    )
    name = models.CharField(
        max_length=256,
        db_index=True,
        verbose_name='Назва'
    )
    slug = models.SlugField(
        max_length=256,
        db_index=True
    )
    image = models.ImageField(
        upload_to='prod_img/',
        blank=True,
        verbose_name='Зображення'
    )
    desc = models.TextField(
        blank=True,
        verbose_name='Опис'
    )
    price = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        verbose_name='Ціна'
    )
    stock = models.PositiveIntegerField(
        verbose_name='Запас'
    )
    available = models.BooleanField(
        default=True,
        verbose_name='Наявність'
    )
    created = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Створено')
    updated = models.DateTimeField(
        auto_now=True,
        verbose_name='Оновлено')

    class Meta:
        ordering = ['name']
        index_together = [
            ['id', 'slug']
        ]
        verbose_name = 'Товар'
        verbose_name_plural = 'Товари'

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('shop:ProductDetail', args=[self.id, self.slug])

Picture for better understanding
5b8c0e26e77fa846256658.jpeg

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Stormwalker, 2018-09-03
@Stormwalker

If you want to have one view for filtered and unfiltered products, then you need to check the category in the arguments earlier. I would also move the page into the view arguments.

V
vikholodov, 2018-09-03
@vikholodov

paginator = Paginator(products, 6) drop below the if category_slug check. The paginator does not care what Queryset to process, therefore, if the check works, then the filtered goods will get into the paginator, if not, then no =)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question