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

Django项目提交表单时遇AttributeError: 'QuerySet'无'name'属性

解决Django创建物品时分类判断的AttributeError问题

错误原因

报错行if category == all_categories.name:存在两个核心问题:

  • Category.objects.filter(name=category)返回的是QuerySet对象(匹配条件的分类集合),而非单个Category实例,QuerySet没有.name属性,直接访问会触发AttributeError。
  • 即使获取到有效分类对象,原逻辑中把字符串category直接赋值给AuctionItem的category外键字段也是错误的——外键字段必须接收Category模型实例,不能传入字符串。

修复方案

推荐使用Django内置的get_or_create()方法,该方法会自动检查数据库中是否存在指定条件的记录:存在则返回现有对象,不存在则创建新对象,一行代码即可完成判断+创建逻辑,避免手动判断的冗余和错误。

修正后的create_listing视图函数

@login_required 
def create_listing(request):
    if request.method == "POST":
        title = request.POST["title"]
        description = request.POST["description"]
        price = request.POST["price"]
        image = request.POST["image"]
        category_name = request.POST["category"]  # 重命名变量,语义更清晰
    
        # get_or_create返回元组:(对象, 是否新建)
        category_obj, _ = Category.objects.get_or_create(name=category_name)
    
        # 创建物品时传入Category实例
        item = AuctionItem.objects.create(
            user=request.user,
            title=title,
            description=description,
            price=price,
            image=image,
            category=category_obj
        )

        return HttpResponseRedirect(reverse("index"))

    return render(request, "auctions/create_listing.html")

手动判断的替代方案(不依赖get_or_create)

如果需要手动实现判断逻辑,可按以下方式修改:

@login_required 
def create_listing(request):
    if request.method == "POST":
        # ... 其他字段获取代码 ...
        category_name = request.POST["category"]
    
        # 检查分类是否存在
        category_query = Category.objects.filter(name=category_name)
        if category_query.exists():
            category_obj = category_query.first()  # 取第一个匹配的分类对象
        else:
            category_obj = Category.objects.create(name=category_name)
    
        # 创建物品
        item = AuctionItem.objects.create(
            user=request.user,
            title=title,
            description=description,
            price=price,
            image=image,
            category=category_obj
        )

        return HttpResponseRedirect(reverse("index"))

    return render(request, "auctions/create_listing.html")

额外优化建议

  • 为Category模型的name字段添加unique=True约束,彻底避免重复创建同名分类:
    class Category(models.Model):
        name = models.CharField(max_length=64, unique=True)  # 移除null=True,分类名称不应为空
    
  • 建议使用Django表单类(ModelForm)处理提交逻辑,自动完成字段验证、类型转换,减少手动操作POST数据的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 17:06:32