为了账号安全,请及时绑定邮箱和手机立即绑定

单击 Django 中的按钮时出现类型错误和断言错误

单击 Django 中的按钮时出现类型错误和断言错误

慕容708150 2023-08-08 10:20:51
对长篇文章表示歉意,我正在尝试实现一个简单的按钮,可以从监视列表中添加或删除项目。虽然我最初设法正确地实现了“addwatchlist”功能,但我修改了代码几个小时,但我有点无法再次理解它。这是按“添加到监视列表”按钮时收到的错误:TypeError at /addwatchlist/10Field 'id' expected a number but got <Listing: "Gloss + Repair Spray">.Request Method:     GETRequest URL:    http://127.0.0.1:8000/addwatchlist/10Django Version:     3.1.1Exception Type:     TypeErrorException Value:    Field 'id' expected a number but got <Listing: "Gloss + Repair Spray">.追溯 :watchlist.save()▼ Local varsVariable    Valueid          10request     <WSGIRequest: GET '/addwatchlist/10'>watchlist   Error in formatting: TypeError: Field 'id' expected a number but got <Listing: "Gloss + Repair Spray">.这是我在按下“从监视列表中删除”按钮时收到的错误,请注意,这与我最初收到的错误完全相同,这反过来又迫使我尝试调整“添加到监视列表”功能的方式:AssertionError at /removewatchlist/1Watchlist object can't be deleted because its id attribute is set to None.Request Method:     GETRequest URL:    http://127.0.0.1:8000/removewatchlist/1Django Version:     3.1.1Exception Type:     AssertionErrorException Value:    Watchlist object can't be deleted because its id attribute is set to None.追溯 :watchlist.delete()▼ Local varsVariable    Valueid          1request     <WSGIRequest: GET '/removewatchlist/1'>watchlist   <Watchlist: 1 Watchlist ID# None : admin watchlisted : "Iphone 11 Pro">Models.py :class Listing(models.Model):    owner = models.CharField(max_length=64)    title = models.CharField(max_length=64)    description = models.TextField(max_length=1024)    startingBid = models.IntegerField()    link = models.URLField(blank=True)    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="category_id")    time = models.DateTimeField(auto_now_add=True)    active = models.BooleanField(null=False, default='True')    def __str__(self):        return f'"{self.title}"'
查看完整描述

2 回答

?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

根据您的具体错误,问题出在这一行,从错误消息中应该可以清楚地看出:

watchlist = Watchlist(user=request.user.username,watchlist_listingid_id=Listing.objects.filter(id=id).first())

id 需要一个 int (模型实例的 id),但实际上您正在向它传递一个列表模型的对象实例;filter() 返回一个查询集,然后 .first() 返回该查询集中的第一个对象。

这就是为什么错误告诉您“field id”(需要一个 int),而是得到“<Listing:“Gloss + Repair Spray">”——这是您的 Listing 模型的实际实例。

解决方案:只需在 .first() 之后添加 .id 就可以解决您的问题,因此您实际上将该对象的 id 传递给 id 字段:

watchlist = Watchlist(user=request.user.username,watchlist_listingid_id=Listing.objects.filter(id=id).first().id)

这应该可以解决您的具体问题;尽管如此,我还是强烈建议您对这些按钮使用表单。目前,您允许以不安全的方式修改数据库的内容。任何修改数据库内容的活动都应作为 POST 请求进行传递。即使您没有使用任何实际的输入字段,您也可以很容易地使用表单来完成此操作。该按钮将提交空表单作为 POST 请求,您可以在模板的表单标记中包含 csrf 令牌,并且数据库将进行相应修改。如果您确实不想使用表单,另一种选择是使用 AJAX 调用(通过 jQuery),该调用可以作为 POST 请求发送,而无需使用表单。

最后,如果监视列表与用户绑定,您可能应该考虑完全不同的数据库模式来获取结果 - 也就是说,实际上将用户模型与他们添加到监视列表中的项目相关联(不过,这是可能的,我误解了你的意图,也许你不希望这样)。您可以通过多对多关系连接用户模型和列表模型,因为用户可以“监视”许多列表,并且列表可以被许多用户“监视”。


查看完整回答
反对 回复 2023-08-08
?
炎炎设计

TA贡献1808条经验 获得超4个赞

修复:“字段‘id’需要一个数字,但得到<列表:“光泽+修复喷雾”>。”

只需在 .first() 之后添加 .id

watchlist = Watchlist(user=request.user.username,watchlist_listingid_id=Listing.objects.filter(id=id).first() = <Listing: "Gloss + Repair Spray">

watchlist = Watchlist(user=request.user.username,watchlist_listingid_id=Listing.objects.filter(id=id).first().id) = 6 (which is the ID in my database)

修复:无法删除监视列表对象,因为其 id 属性设置为 None。

watchlist = Watchlist.objects.get(user=request.user.username, watchlist_listingid=id)

在使用 delete() 之前获取表中的整行并将其分配给变量

而不是有缺陷的:

watchlist = Watchlist(user=request.user.username,watchlist_listingid_id=id)

最后,我发现要在同一个 HTML 页面中使用不同的 Django 表单,您可以将表单的操作设置为 URLS.PY 中的路径 url,然后这将触发 Views.py 中的特殊函数。


查看完整回答
反对 回复 2023-08-08
  • 2 回答
  • 0 关注
  • 93 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信