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

对长篇文章表示歉意,我正在尝试实现一个简单的按钮,可以从监视列表中添加或删除项目。


虽然我最初设法正确地实现了“addwatchlist”功能,但我修改了代码几个小时,但我有点无法再次理解它。


这是按“添加到监视列表”按钮时收到的错误:


TypeError at /addwatchlist/10


Field 'id' expected a number but got <Listing: "Gloss + Repair Spray">.


Request Method:     GET

Request URL:    http://127.0.0.1:8000/addwatchlist/10

Django Version:     3.1.1

Exception Type:     TypeError

Exception Value:    


Field 'id' expected a number but got <Listing: "Gloss + Repair Spray">.

追溯 :


watchlist.save()


▼ Local vars

Variable    Value

id          10


request     <WSGIRequest: GET '/addwatchlist/10'>


watchlist   Error in formatting: TypeError: Field 'id' expected a number but got <Listing: "Gloss + Repair Spray">.

这是我在按下“从监视列表中删除”按钮时收到的错误,请注意,这与我最初收到的错误完全相同,这反过来又迫使我尝试调整“添加到监视列表”功能的方式:


AssertionError at /removewatchlist/1


Watchlist object can't be deleted because its id attribute is set to None.


Request Method:     GET

Request URL:    http://127.0.0.1:8000/removewatchlist/1

Django Version:     3.1.1

Exception Type:     AssertionError

Exception Value:    


Watchlist object can't be deleted because its id attribute is set to None.

追溯 :


watchlist.delete()


▼ Local vars

Variable    Value

id          1


request     <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}"'



慕容708150
浏览 148回答 2
2回答

尚方宝剑之说

根据您的具体错误,问题出在这一行,从错误消息中应该可以清楚地看出: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 请求发送,而无需使用表单。最后,如果监视列表与用户绑定,您可能应该考虑完全不同的数据库模式来获取结果 - 也就是说,实际上将用户模型与他们添加到监视列表中的项目相关联(不过,这是可能的,我误解了你的意图,也许你不希望这样)。您可以通过多对多关系连接用户模型和列表模型,因为用户可以“监视”许多列表,并且列表可以被许多用户“监视”。

炎炎设计

修复:“字段‘id’需要一个数字,但得到<列表:“光泽+修复喷雾”>。”只需在 .first() 之后添加 .idwatchlist&nbsp;=&nbsp;Watchlist(user=request.user.username,watchlist_listingid_id=Listing.objects.filter(id=id).first()&nbsp;=&nbsp;<Listing:&nbsp;"Gloss&nbsp;+&nbsp;Repair&nbsp;Spray"> watchlist&nbsp;=&nbsp;Watchlist(user=request.user.username,watchlist_listingid_id=Listing.objects.filter(id=id).first().id)&nbsp;=&nbsp;6&nbsp;(which&nbsp;is&nbsp;the&nbsp;ID&nbsp;in&nbsp;my&nbsp;database)修复:无法删除监视列表对象,因为其 id 属性设置为 None。watchlist&nbsp;=&nbsp;Watchlist.objects.get(user=request.user.username,&nbsp;watchlist_listingid=id)在使用 delete() 之前获取表中的整行并将其分配给变量而不是有缺陷的:watchlist&nbsp;=&nbsp;Watchlist(user=request.user.username,watchlist_listingid_id=id)最后,我发现要在同一个 HTML 页面中使用不同的 Django 表单,您可以将表单的操作设置为 URLS.PY 中的路径 url,然后这将触发 Views.py 中的特殊函数。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python