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

Django获取特定分类Listing报错:Field 'id'期望数字却获'Jewelries'

问题描述

尝试获取特定分类下的Listing数据时,选择分类触发如下错误:

ValueError at /categories_view Field 'id' expected a number but got 'Jewelries'.

相关代码

views.py

def index(request):
    listings = Listing.objects.filter(is_active=True)
    product_ca = Category.objects.all()
    return render(request, "auctions/index.html", {
        "data": listings,
        "categ": product_ca
    })


def categories_view(request):
    if request.method == "POST":
        c = request.POST["categorys"]
        cg = Listing.objects.filter(category=c)
        cg.category_id
        return render(request, "auctions/Categories_view.html", {
        "category": cg,
    })

models.py

class Category(models.Model):
    type = models.CharField(max_length=100, null=True)
    
    def __str__(self):
        return self.type
    

class Listing(models.Model):
    product_name = models.CharField(max_length=64, verbose_name="product_name")
    product_description = models.TextField(max_length=200, verbose_name="product description")
    product_image = models.ImageField(upload_to="images/", verbose_name="image", blank=True)
    is_active = models.BooleanField(blank=False, default=True)
    price_bid = models.DecimalField(decimal_places=2, max_digits=6, default=False)
    owner = models.ForeignKey(User, related_name="auction_owner", on_delete=models.CASCADE, default=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="category")

用户疑问:需要获取c = request.POST["categorys"]对应的id来查询Listing,但不确定具体实现方式,或思路可能有误。


解决方案

错误核心原因:Listing的category是外键字段,Django默认会将过滤值匹配到Category的主键(id),但你传入的是分类名称(如'Jewelries'),导致类型不匹配。以下两种方案可解决:

方案一:基于分类名称查询(适配当前前端传值逻辑)

直接通过分类名称跨表过滤Listing,无需先查Category对象:

def categories_view(request):
    if request.method == "POST":
        category_name = request.POST["categorys"]
        # 用双下划线跨表匹配Category的type字段
        cg = Listing.objects.filter(category__type=category_name)
        # 删掉无意义的cg.category_id行
        return render(request, "auctions/Categories_view.html", {
            "category": cg,
        })

方案二:基于分类ID查询(更高效,推荐)

修改前端表单,让下拉框的value传递分类ID而非名称,后端直接用ID过滤:

前端模板(index.html)修改

<form method="POST" action="{% url 'categories_view' %}">
    {% csrf_token %}
    <select name="categorys">
        {% for cat in categ %}
            <!-- 将value从分类名称改为ID -->
            <option value="{{ cat.id }}">{{ cat.type }}</option>
        {% endfor %}
    </select>
    <button type="submit">筛选</button>
</form>

后端views.py修改

def categories_view(request):
    if request.method == "POST":
        category_id = request.POST["categorys"]
        # 直接用category_id过滤,Django自动匹配外键主键
        cg = Listing.objects.filter(category_id=category_id)
        return render(request, "auctions/Categories_view.html", {
            "category": cg,
        })

额外优化提示
  1. 代码中cg.category_id一行无实际作用,可直接删除;
  2. Listing的price_bid字段default=False不合理,DecimalField默认值应为数字,比如default=0.00;
  3. owner字段default=True存在逻辑问题,ForeignKey默认应设置为用户ID或允许为空(null=True),建议创建Listing时动态赋值为当前请求用户。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 11:52:21