How can I refer to an certain model via URL?

Hello!

I have a problem and I cant figure it out so I am asking your guys help.
On the picture you see ‘All products’ I want it to change as I change to a different category. For example if I would choose category ‘Electronics’ instead of ‘All products’ it would display 'Electronics.

models.py

class Product(models.Model):
    name = models.CharField(max_length=120)
    quantity = models.IntegerField(null=True, blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    description = models.TextField(blank=True, null=True)
    image = models.ImageField(blank=True, null=True)
    category = models.ForeignKey(
        'Category',
        on_delete=models.DO_NOTHING,
    )

    def __str__(self):
        return self.name


class Category(models.Model):
    name = models.CharField(max_length=60)

    def __str__(self):
        return self.name

template
The name would be between {% block header %}

<div class="jumbotron jumbotron-fluid" style="margin: 0px; text-align: center;">
        <div class="container">
            <h1 class="display-4">{% block header %}{% endblock %}</h1>
            <p class="lead">
                {% if user.is_authenticated %}
                Logged in: {{ user }}
                {% endif %}

            </p>
        </div>
    </div>

views.py

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

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

        category_id = self.request.GET.get('category', None)
        search = self.request.GET.get('search', None)

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

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

        return products

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

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

        return context

urls for this page

path('products_list', views.ProductsListView.as_view(), name='products')

If you need additional information just let me know as I am not really sure what I have to add here

What does that part of your template look like? (How are you displaying “All Products”?)

(Also, when posting code or templates here, please enclose it between lines of three backtick - ` characters. That means you’ll have a line of ```, followed by your code, followed by another line of ```.)

In models.py you can add a static method like,
@staticmethod
def get_all_products_by_id(category_id):
return Product.objects.filter(category = category_id)

and in views.py,
categoryID = request.GET.get(‘category’)
products =Product.get_all_products_by_id(categoryID)

and i am thinking you know how to render it in html file.
hope your doubt will clear.

Thank you so much for advising me to use backticks. It really make things a lot clearer and I also added the template code now.
Cheers

Hey

I am going to give it a try. Thank you for helping
cheers

I am not sure where I have to add these things in views.py and I guess you mean by rendering using this? {{ }}

In your get_context_data method, you’re adding things to your context dictionary. The context is a dict containing values available to be rendered in a template.

You’re already adding categories to the context. You can add title (if that’s what you want to call it) to your context, and then render it in your template as {{ title }}.

Ok but how do I add title there? How do i make it get the category id from the url? by .GET?

What does your urls.py file look like? (How this this view being invoked?) What do the links look like in the page that sends you here?

Hey

Added the urls.py for that page

So it doesn’t look like you’re taking the category in the URL. Where are you planning to get the category from?

From there:

Ok, so you’re accepting it as a query variable. That means that you should have access to it in your CBV via self.kwargs[‘category’]. That will give you the category ID from which you can retrieve the title from your Category model.

Like that?

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

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

        title = self.kwargs['category']
        context['title'] = title

        return context

So what happens when you try it?

The way I added it:
Its in the base.html

<div class="jumbotron jumbotron-fluid" style="margin: 0px; text-align: center;">
        <div class="container">
            <h1 class="display-4">{% block header %}{% endblock %}</h1>
            <p class="lead">
                {% if user.is_authenticated %}
                Logged in: {{ user }}
                {% endif %}

            </p>
        </div>
    </div>

in the products_list.html its just

{% block header %} {{ title } {% endblock %}
``

I fixed the typo but error still remains.

Oops, I apologize - that’s what I get for relying upon my memory instead of double-checking myself. You were right the first time - you would reference it the same way that you’re referencing it in your get_queryset method.
That’s retrieving the id - then you want to use that id in a query to get the actual title.

Thats fine. Thanks a for sticking by and helping to solve my problem. I am not sure what I have to do now. Please, if you can, tell me more what you mean. Regardless I am trying to do what you are telling me now.

Update:
I got it to show the ID now! Now I am trying to figure out how can I get the name.

Code

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

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

        title = self.request.GET.get('category', None)
        context['title'] = title
        return context
````