You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Django中基于Category Model实现商品分类筛选、导航栏展示及HTML渲染的技术咨询

Solution for E-commerce Category Filtering & Navigation

Let's fix your code issues and walk through how to implement category-based product filtering, add categories to your navigation bar, and render everything in HTML.

1. Fix the CategoryView in views.py

Your current CategoryView has two critical issues: it doesn't retrieve the slug from the request (so the variable is undefined) and it fetches all categories instead of the specific one the user clicked on. Here's the corrected version:

from django.shortcuts import render, get_object_or_404
from django.views import View
from .models import Product, Category

class ProductView(View):
    def get(self, request, *args, **kwargs):
        products = Product.objects.filter(is_active=True)
        # Pass all categories to the template for navigation bar rendering
        categories = Category.objects.all()
        context = {
            'products': products,
            'categories': categories
        }
        return render(request, 'Product/products.html', context)

class ProductDetailView(View):
    def get(self, request, slug):
        # Use get_object_or_404 to handle missing products gracefully (avoids crashes)
        product = get_object_or_404(Product, slug=slug)
        categories = Category.objects.all()
        context = {
            'product': product,
            'categories': categories
        }
        return render(request, 'Product/productdetail.html', context)

class CategoryView(View):
    def get(self, request, slug):
        # Fetch the specific category using its slug
        current_category = get_object_or_404(Category, slug=slug)
        # Filter products to only active items in this category
        products = Product.objects.filter(category=current_category, is_active=True)
        # Pass all categories for consistent navigation
        all_categories = Category.objects.all()
        context = {
            'current_category': current_category,
            'products': products,
            'categories': all_categories
        }
        return render(request, 'Product/category.html', context)

2. Configure URLs (urls.py)

Map your views to URLs so users can access category pages and product details. Add these paths to your app's urls.py:

from django.urls import path
from . import views

urlpatterns = [
    path('', views.ProductView.as_view(), name='product-list'),
    path('product/<slug:slug>/', views.ProductDetailView.as_view(), name='product-detail'),
    path('category/<slug:slug>/', views.CategoryView.as_view(), name='category-detail'),
]

3. Add Categories to Navigation Bar (Base Template)

Create a base.html template that all other templates extend — this ensures your navigation bar appears on every page:

<!DOCTYPE html>
<html>
<head>
    <title>Your E-commerce Store</title>
</head>
<body>
    <!-- Navigation Bar -->
    <nav style="margin-bottom: 20px;">
        <a href="{% url 'product-list' %}">Home</a>
        <span style="margin: 0 10px;">|</span>
        {% for category in categories %}
            <a href="{% url 'category-detail' category.slug %}">{{ category.category }}</a>
            {% if not forloop.last %}<span style="margin: 0 10px;">|</span>{% endif %}
        {% endfor %}
    </nav>

    <!-- Content Block (overridden by child templates) -->
    {% block content %}{% endblock %}
</body>
</html>

4. Render Products in Templates

Product List Page (products.html)

Extend the base template and loop through all active products:

{% extends 'base.html' %}

{% block content %}
    <h1>All Products</h1>
    <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px;">
        {% for product in products %}
            <div style="border: 1px solid #eee; padding: 15px; border-radius: 8px;">
                {% if product.image %}
                    <img src="{{ product.image.url }}" alt="{{ product.title }}" style="width: 100%; height: 200px; object-fit: cover;">
                {% endif %}
                <h3 style="margin-top: 10px;">
                    <a href="{% url 'product-detail' product.slug %}">{{ product.title }}</a>
                </h3>
                <p style="color: #888; margin: 5px 0;">Category: {{ product.category.category }}</p>
                <p style="font-weight: bold; font-size: 1.1em;">${{ product.selling_price }}</p>
            </div>
        {% empty %}
            <p>No active products available right now.</p>
        {% endfor %}
    </div>
{% endblock %}

Category Page (category.html)

Render products filtered to the selected category:

{% extends 'base.html' %}

{% block content %}
    <h1>{{ current_category.category }}</h1>
    <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px;">
        {% for product in products %}
            <div style="border: 1px solid #eee; padding: 15px; border-radius: 8px;">
                {% if product.image %}
                    <img src="{{ product.image.url }}" alt="{{ product.title }}" style="width: 100%; height: 200px; object-fit: cover;">
                {% endif %}
                <h3 style="margin-top: 10px;">
                    <a href="{% url 'product-detail' product.slug %}">{{ product.title }}</a>
                </h3>
                <p style="font-weight: bold; font-size: 1.1em;">${{ product.selling_price }}</p>
            </div>
        {% empty %}
            <p>No products in this category yet.</p>
        {% endfor %}
    </div>
{% endblock %}

Product Detail Page (productdetail.html)

Show individual product details with a link back to its category:

{% extends 'base.html' %}

{% block content %}
    <div style="max-width: 800px; margin: 0 auto;">
        {% if product.image %}
            <img src="{{ product.image.url }}" alt="{{ product.title }}" style="width: 100%; max-height: 400px; object-fit: contain;">
        {% endif %}
        <h1>{{ product.title }}</h1>
        <p style="color: #888;">Category: <a href="{% url 'category-detail' product.category.slug %}">{{ product.category.category }}</a></p>
        <p style="margin: 10px 0;">Original Price: <del>${{ product.actual_price }}</del></p>
        <p style="font-weight: bold; font-size: 1.2em;">Selling Price: ${{ product.selling_price }}</p>
        <div style="margin-top: 20px;">
            <h3>Description</h3>
            <p>{{ product.description }}</p>
        </div>
    </div>
{% endblock %}

Quick Model Improvement

Your Product model has a confusing field name: product = models.ForeignKey(Seller, ...) — rename this to seller to avoid mixing up the product with its seller. Run a migration after making the change:

# Updated Product model field
seller = models.ForeignKey(Seller, on_delete=models.CASCADE)

内容的提问来源于stack exchange,提问作者Dhiman

火山引擎 最新活动