Search code examples
pythonhtmldjangomodel

How can I click on any of the categories in the list and be redirected to all active listings in that category? Django


Im working on a django project (im newb) and I`ve made a html page displaying a list of available categories. I want to make each a link and when the user clicks it he/she should be redirected to a list of active listings based on that category. I simply cannot understand how. Here is my code:

models.py

class Category(models.Model):
    category = models.CharField(max_length=64)

    def __str__(self):
        return self.category


class Listings(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
    title = models.CharField(max_length=128)
    description = models.CharField(max_length=822)
    price = models.FloatField()
    sold = models.BooleanField(default=False)
    category = models.ForeignKey(Category, on_delete=models.CASCADE,blank=True, null=True, 
    related_name="listings_category")
    categories = models.ManyToManyField(Category, blank=True, related_name="select_category")
    image_url = models.CharField(max_length=128,blank=True, null=True)
    
    def __str__(self):
        return f"{self.title}"

urls.py

path('category/', views.category, name="category"),

path("listing/<str:listing_id>", views.listing, name="listing")

views.py

def category(request):
    cat = Category.objects.filter().values('category')
    category_id = Category.objects.filter().values('id')
    z = []
    for c in category_id:
        z.append(c['id'])
    
    listing = Listings.objects.filter(category__in= z)
    categories = Category.objects.all()
    category = Category.objects.filter(id__in=z)
    print(category)

    return render(request, "auctions/category.html",{
        "categories":categories,
        "category":category,
        "listing":listing
    })

def listing(request, listing_id):
        listing = Listings.objects.get(id=listing_id)
        user = request.user
        owner = True if listing.user == user else False
        category = Category.objects.get(category=listing.category)
        comments = Comments.objects.filter(listing=listing.id)
        watching = WatchList.objects.filter(user = user, listing = listing)
       
        if request.method == "POST":
            comment = request.POST["comment"]
            
            if comment != '':
                Comments.objects.create(user=user, listing=listing, comment=comment)
                return HttpResponseRedirect(listing_id)

        return render(request, "auctions/listing.html", {
                "listing": listing,
                "category": category,
                "owner": owner,
                "comments": comments,
                "watching": WatchList.objects.filter(user = user, listing = 
                listing).values('watching'),
            })
 

HTML

{% block body %}
    {% for cat in category %}
    <ul>
        <li>
            <a href="">{{ cat.category }}</a>
        </li>
    </ul>
    {% endfor %}
{% endblock %}

Ive got the link (Category) to render the html page with the list of available categories but I cant link them to their respective active listings from the database. Any help would be greatly apreciated.


Solution

  • You need to add a url for the listing list, and then a view that handles it, as well as a template.

    in urls.py:

    path('category/<int:category_id>', views.listing_list, name="listing_list"),

    in views.py (make sure to set the template name in the render call):

    def listing_list(request, category_id):
        from django.shortcuts import get_object_or_404
        category = get_object_or_404(Category, pk=category_id)
        # use a reverse lookup on listings_category foreign key name
        listings = category.listings_category.all()
    
        return render(request, "auctions/<template name goes here>.html",{
            "category":category,
            "listings":listings
        })
    

    In your template you will have the category object as well as all listings that belong to it in the context.

    Then in your auctions/category.html you will need to change your HTML:

    {% block body %}
        {% for cat in category %}
        <ul>
            <li>
                <a href="{% url 'listing_list' category_id=cat.pk %}">{{ cat.category }}</a>
            </li>
        </ul>
        {% endfor %}
    {% endblock %}