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

Django拍卖应用创建Listing时遇TypeError:字段'id'需数字却获内置函数id

Django拍卖应用创建Listing时TypeError问题排查与修复

问题现象

开发基于Django的拍卖应用时,创建新Listing触发TypeError:

Type Error at /create "Field 'id' expected a number but got "

错误指向views.py第81行代码:

viewListing = Listing.objects.get(pk=id)

期望创建完成后重定向到包含新Listing的index视图,需修复代码使其正常运行。


相关代码片段

views.py 创建视图

@login_required
def create(request):
    if request.method == "GET":
        categories = Category.objects.all()
        return render(request, "auctions/create.html", {
            "categories": categories
        })
    else:
        title = request.POST["title"]
        description = request.POST["description"]
        image = request.POST["image"]
        price = request.POST["price"]
        category = request.POST["category"]
        categories = Category.objects.get(categoryType=category)
        sessionUser = request.user
        viewListing = Listing.objects.get(pk=id)
        viewListing.watchlist.add(sessionUser)
        
        bid = Bid(bid=float(price), user=sessionUser)
        bid.save()
        
        listing = Listing(
            title=title,
            description=description,
            image=image,
            price=bid,
            category=categories,
            owner=sessionUser
        )
        listing.save()
        return HttpResponseRedirect(reverse(index))

urls.py 路由配置

from django.urls import path

from . import views

urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("register", views.register, name="register"),
path("create", views.create, name="create"),
path("categories/", views.categories, name="categories"),
path("filter/<int:category_id>", views.filter, name="filter"),
path("listing/<int:id>", views.listing, name="listing"),
path("remove/<int:id>", views.remove, name="remove"),
path("add/<int:id>", views.add, name="add"),
path("watchlist", views.watchlist, name="watchlist"),
path("comment/<int:id>", views.comment, name="comment"),
path("bid/<int:id>", views.bid, name="bid"),
path("close/<int:id>", views.close, name="close")
]

models.py 核心模型

from django.contrib.auth.models import AbstractUser
from django.db import models

class User(AbstractUser):
    pass

class Bid(models.Model):
    bid = models.DecimalField(decimal_places=2, max_digits=7)
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="userBid", null=True, blank=True)

    def __str__(self):
        return f"{self.bid}"

class Listing(models.Model):
    title = models.CharField(max_length=64)
    description = models.CharField(max_length=500)
    price = models.ForeignKey(Bid, on_delete=models.CASCADE, related_name="currentbid", null=True, blank=True)
    active = models.BooleanField(default=True)
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user", null=True, blank=True)
    image = models.CharField(max_length=900)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="category", null=True, blank=True)
    watchlist = models.ManyToManyField(User, null=True, blank=True, related_name="watchlist")
    
    def __str__(self):
        return self.title

class Comment(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True, related_name="author")
    listing = models.ForeignKey(Listing, on_delete=models.CASCADE, blank=True, null=True, related_name="comment")
    message = models.CharField(max_length=500)

    def __str__(self):
        return f"{self.author} comment on {self.listing}"

错误原因分析

  1. 变量名冲突:代码中使用的id是Python内置函数,并非新创建Listing的ID,此时新Listing还未生成,Listing.objects.get(pk=id)自然无法获取到有效对象,触发类型错误。
  2. 逻辑顺序错误:尝试先获取不存在的Listing,再创建Listing,违背了数据生成的先后逻辑。
  3. 重定向参数错误:reverse(index)直接传入视图函数,不符合Djangoreverse函数的使用规范,应传入路由名称字符串。
  4. 价格类型不匹配:用float(price)转换价格,与Bid模型中的DecimalField类型不匹配,易引发精度问题。

修复后的代码(views.py)

from decimal import Decimal  # 需要导入Decimal

@login_required
def create(request):
    if request.method == "GET":
        categories = Category.objects.all()
        return render(request, "auctions/create.html", {
            "categories": categories
        })
    else:
        title = request.POST["title"]
        description = request.POST["description"]
        image = request.POST["image"]
        price = request.POST["price"]
        category = request.POST["category"]
        categories = Category.objects.get(categoryType=category)
        sessionUser = request.user
        
        # 用Decimal处理价格,匹配模型字段类型
        bid = Bid(bid=Decimal(price), user=sessionUser)
        bid.save()
        
        # 先创建并保存Listing对象
        listing = Listing(
            title=title,
            description=description,
            image=image,
            price=bid,
            category=categories,
            owner=sessionUser
        )
        listing.save()
        
        # 若需将创建者加入该Listing的关注列表,执行此操作
        listing.watchlist.add(sessionUser)
        
        # 用路由名称执行重定向
        return HttpResponseRedirect(reverse("index"))

关键修复点说明

  • 移除错误的Listing.objects.get(pk=id)及后续无效操作,改为创建Listing后再处理关注列表(如果业务需要)。
  • 替换float(price)为Decimal(price),确保价格类型与模型字段一致,避免精度丢失。
  • 重定向时使用reverse("index"),对应urls.py中name="index"的路由配置,保证跳转正确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 04:31:26