mascai
mascai

Reputation: 1852

Django ListView filter objects

I have a simple structure Shop_list --> Product_list --> Product_detail

I want to filter Product class object by slug field, but I see zero products.

I think that the problem in get_queryset()

views.py

class HomePageView(ListView):
    model = Shop
    template_name = 'blog/shop_list.html'
    page_kwarg = 'shop'
    context_object_name = 'shops'


class ProductListView(ListView):
    model = Product
    template_name = 'blog/product_list.html'
    page_kwarg = 'product'
    context_object_name = 'products'

    def get_queryset(self):
        pattern = str(self.request)
        pattern = pattern[1:]
        slug = self.model.shop
        return Product.objects.filter(shop__slug=pattern)


def produt_detail(request, **kwargs):
    print(request)
    product = get_object_or_404(Product, pk=kwargs["pk"])
    return render(request, 'blog/product_detail.html', {'product': product})

models.py

class Shop(models.Model):
    title = models.CharField(max_length=200)
    image = models.ImageField(blank=True)
    slug = models.SlugField(null=False, default="Shop")

    def get_absolute_url(self):
        return reverse('product_list', kwargs={'slug': self.slug})


class Product(models.Model):
    shop = models.ForeignKey(Shop, on_delete=models.CASCADE, related_name="shop")
    title = models.CharField(max_length=200)
    price = models.CharField(max_length=200)
    period_start = models.DateTimeField(blank=True, null=True)
    period_end = models.DateTimeField(blank=True, null=True)

    def get_absolute_url(self):
        return reverse('product_detail', kwargs={'slug': self.shop.slug, 'pk': self.pk})

urls.py

urlpatterns = [
    path('', HomePageView.as_view(), name='shop_list'),
    path('<slug:slug>', ProductListView.as_view(), name='product_list'),
    path('<slug:slug>/<int:pk>/', views.produt_detail, name='product_detail'),
]

product_list.html

{% for product in products %}
    <a href="{% url 'product_detail' product.shop.slug product.shop.pk %}">
   ...

Upvotes: 1

Views: 2200

Answers (2)

PrynsTag
PrynsTag

Reputation: 311

You can reduce the redundant code since you already defined your model field in your class based view:

class ProductListView(ListView):
    model = Product
    template_name = 'blog/product_list.html'
    page_kwarg = 'product'
    context_object_name = 'products'

    def get_queryset(self):
        return super().get_queryset().filter(shop__slug=self.kwargs['slug'])

Upvotes: 0

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476557

You filter with:

class ProductListView(ListView):
    model = Product
    template_name = 'blog/product_list.html'
    page_kwarg = 'product'
    context_object_name = 'products'

    def get_queryset(self):
        return Product.objects.filter(shop__slug=self.kwargs['slug'])

Upvotes: 4

Related Questions