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

Django开发eBay类拍卖网站 创建Bid关联Listing时报id期望数字错误

报错原因及解决方案

核心问题梳理

  1. 模型字段默认值类型不匹配
    你在Bid模型的listing外键字段、Listing模型的category外键字段都设置了default="",外键字段本质存储的是关联表的主键ID(数字类型),空字符串是字符串类型,赋值时就会触发「期望得到数字但拿到空字符串」的报错。
  2. 外键关联操作方法错误
    ForeignKey是单对多关联,不是多对多ManyToManyField,不能使用.add()方法关联对象,你写的b.listing.add(l.id)是完全错误的用法。
  3. 额外代码隐患
    Bid模型的__str__方法中调用了self.slug,但你的Bid模型根本没有定义slug字段,后续运行到相关逻辑时也会触发属性不存在的报错。

修正后代码

models.py

class Listing(models.Model):
    title = models.CharField(max_length=200)
    description = models.CharField(max_length=500)
    url = models.URLField()
    author = models.ForeignKey('User', on_delete=models.CASCADE, related_name='listings')
    # 移除错误的空字符串默认值,外键默认值不能为字符串类型
    category = models.ForeignKey('Category', on_delete=models.CASCADE, related_name='listings')

    def __str__(self):
        return f'{self.id}: {self.title}'

class Bid(models.Model):
    price = models.DecimalField(decimal_places=2, max_digits=10)
    bid_count = models.IntegerField(default=0) # 直接设置默认值更合理
    # 移除错误的空字符串默认值
    listing = models.ForeignKey('Listing', on_delete=models.CASCADE, related_name='bids')

    def __str__(self):
        # 替换不存在的slug字段,避免后续报错
        return f'Bid {self.id} for {self.listing.title} ({self.price})'

views.py

def newListing(request):
    try:
        if request.method == "POST":
            newListingForm = NewListingForm(request.POST)
            if newListingForm.is_valid():
                title = newListingForm.cleaned_data['title']
                description = newListingForm.cleaned_data['description']
                url = newListingForm.cleaned_data['url']
                bid = newListingForm.cleaned_data['bid']
                # ModelChoiceField的cleaned_data直接返回模型实例,不需要额外查询
                category = newListingForm.cleaned_data['category']
                current_user = request.user
                l = Listing(title=title, description=description, url=url, author=current_user, category=category)
                l.save()
                # 直接在创建Bid时传入关联的Listing实例,不需要调用add方法
                Bid.objects.create(price=bid, bid_count=0, listing=l)
                return HttpResponseRedirect(reverse("index"))
        else:
            newListingForm = NewListingForm()
            return render(request, "auctions/newListing.html", {
                'form': newListingForm
            })
    except Exception as exc:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        print(exc_type, exc_obj, fname, exc_tb.tb_lineno)
        newListingForm = NewListingForm()
        return render(request, 'auctions/newListing.html', {
            'form': newListingForm
        })

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:45:02