You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django电商网站分类页面404错误排查求助

Django电商网站分类功能404错误排查与解决

问题描述

基于Django框架搭建电商网站时,访问分类页http://127.0.0.1:8000/search/ring/出现404错误,提示“No Category matches the given query”,但商品详情页http://127.0.0.1:8000/item/ring/可正常访问。

错误信息

Page not found (404)
No Category matches the given query.
Request Method: GET
Request URL:    http://127.0.0.1:8000/search/ring/
Raised by:  store.views.category_list
Using the URLconf defined in core.urls, Django tried these URL patterns, in this order:

admin/
[name='all_product']
/item/<slug:slug>/ [name='product_detail']
/search/<slug:category_slug>/ [name='category_list']
The current path, search/ring/, matched the last one.

You’re seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.

相关代码

urls.py

from django.urls import path

from . import views

app_name = 'store'

urlpatterns = [
    path('', views.all_product, name='all_product'),
    path('item/<slug:slug>/', views.product_detail, name='product_detail'),
    path('search/<slug:category_slug>/', views.category_list, name='category_list'),
]

views.py

from django.shortcuts import get_object_or_404, render

from .models import  Product, Category

# Create your views here.
def categories(request):
    return {
        'categories': Category.objects.all()
    }


def all_product(request):
    product = Product.objects.all()
    return render(request, 'store/home.html', {'product': product})


def category_list(request, category_slug):
    category = get_object_or_404(Category, slug=category_slug)
    product = Product.objects.filter(category=category)
    return render(request, 'store/products/category.html', {'category': category, 'product': product})

def product_detail(request, slug):
    product = get_object_or_404(Product, slug=slug, in_stock=True)
    return render(request, 'store/products/detail.html', {'product': product})

models.py

from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
# Create your models here.
class Category(models.Model):
    name = models.CharField(max_length=100, db_index=True)
    slug = models.SlugField(max_length=100, unique=True)
    
    class meta:
        verbose_name_plural = 'categories'
        
        
    def get_absolute_url(self):
        return reverse('store:category_list', args=[self.slug])
        
    def __str__(self):
        return self.name
    
class Product(models.Model):
    category = models.ForeignKey(Category, related_name='product' , on_delete= models.CASCADE)
    created_by= models.ForeignKey(User, on_delete=models.CASCADE, related_name='product_creator' )
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100, default='admin')
    description = models.TextField(blank=True)
    image = models.ImageField(upload_to='images/')
    slug = models.SlugField(max_length=100)
    price = models.DecimalField(max_digits=4, decimal_places=2)
    in_stock = models.BooleanField(default=True)
    is_active = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    update = models.DateTimeField(auto_now=True)
    
    
    class meta:
        verbose_name_plural = 'products'
        ordering = ('-created',)
        
    def get_absolute_url(self):
        return reverse('store:product_detail', args=[self.slug])
    
    
    def __str__(self):
        return self.title

category.html

{% extends "../base.html" %}
{% load static %}
{% block title %}
{% if category %}{{ category.name }}{% else %}Product{% endif %}
{% endblock %}
{% block content %}


<main>
  <div class="album py-5 bg-light">
    <div class="container">

      <div class="pb-3 h5">{{category.name|title}}</div>
      <div class="row row-cols-1 row-cols-sm-2 row-cols-md-5 g-3">

        {% for product in product %}

        <div class="col">
          <div class="card shadow-sm">
          <img class="img-fluid" alt="Responsive image" src="{{ product.image.url }}">

            <div class="card-body">
              <p class="card-text">
                <a class="text-dark text-decoration-none" href="{{ product.get_absolute_url }}">{{ product.title }}</a>
              </p>
              <div class="d-flex justify-content-between align-items-center">
                <small class="text-muted">5 min read</small>
              </div>
            </div>
          </div>
        </div>

        {% endfor %}

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


</main>

{% endblock %}

错误原因

  1. 数据库中无匹配slug的Category:404提示明确说明没有找到slug为ring的分类对象。商品详情页能正常访问是因为Product表中存在slug为ring的商品,Product的slug和Category的slug是两个独立字段,彼此没有关联。
  2. models.py中Meta类拼写错误:Category和Product类中的class meta:应为class Meta:(首字母大写),虽然这不是直接导致404的原因,但会导致Django无法识别复数名称、排序等配置,影响后台管理和模型行为。

解决方法

1. 创建匹配的Category对象

  • 通过后台创建:访问/admin/,进入Category管理页面,添加一个分类,设置slug为ring,保存后重新访问/search/ring/。
  • 通过Python Shell创建:
    python manage.py shell
    
    进入shell后执行:
    from store.models import Category
    Category.objects.create(name='戒指', slug='ring')
    

2. 修正models.py中的Meta类拼写

将Category和Product类中的class meta:修改为class Meta:(首字母大写):

class Category(models.Model):
    # ... 其他字段
    class Meta:
        verbose_name_plural = 'categories'

class Product(models.Model):
    # ... 其他字段
    class Meta:
        verbose_name_plural = 'products'
        ordering = ('-created',)

修改后执行数据库迁移:

python manage.py makemigrations
python manage.py migrate

3. 验证商品与分类的关联

确保slug为ring的Product对象,其category字段关联的是slug为ring的Category。可以在Django后台编辑该商品,选择对应的分类,保存后分类页就能显示该商品。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 21:58:10