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, })
额外优化提示
- 代码中
cg.category_id一行无实际作用,可直接删除; Listing的price_bid字段default=False不合理,DecimalField默认值应为数字,比如default=0.00;owner字段default=True存在逻辑问题,ForeignKey默认应设置为用户ID或允许为空(null=True),建议创建Listing时动态赋值为当前请求用户。
内容的提问来源于stack exchange,提问作者Ogbonna Echefunachukwu
相关产品推荐
相关产品推荐

