微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

单击Django中的按钮时出现TypeError和AssertionError错误

如何解决单击Django中的按钮时出现TypeError和AssertionError错误

很抱歉,我正在尝试实现一个简单的按钮,该按钮可以从监视列表中添加删除项目。

虽然我最初设法适当地实现了“ 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}"'

class Watchlist(models.Model):
    user = models.CharField(max_length=64)
    watchlist_listingid = models.ForeignKey(Listing,related_name="watchlist_listingid",null=True)

    def __str__(self):
        return f'{self.watchlist_listingid_id} Watchlist ID# {self.id} : {self.user} watchlisted : {self.watchlist_listingid}'

Views.py

@login_required
def watchlist(request):
    if request.user.username:
        return render(request,"auctions/watchlist.html",{
        "items" : Watchlist.objects.filter(user=request.user.username),"watchlist_listingid" : Watchlist.objects.values_list('watchlist_listingid',flat=True).filter(user=request.user.username),"watchlist_count" : len(Watchlist.objects.filter(user=request.user.username))
    })

def addwatchlist(request,id):

    if request.user.username:
        watchlist = Watchlist(user=request.user.username,watchlist_listingid_id=Listing.objects.filter(id=id).first())
        watchlist.save()
        return redirect('listing',id=id)

    else:
        return render('auctions/watchlist.html',{})

def removewatchlist(request,id):
        if request.user.username:
        # all_entries = Watchlist.objects.values_list('watchlist_listingid',flat=True).filter(user='admin')
        # for i in all_entries:
        #     if i == id:
        #         removeMe = i
        #     else:
        #         removeMe = 'TEST ERROR'
            watchlist = Watchlist(user=request.user.username,watchlist_listingid_id=id)
            watchlist.delete()
            return redirect('listing',id=id)

Urls.py

path("listing/<int:id>",views.listing,name="listing"),path("watchlist",views.watchlist,name="watchlist"),path("addwatchlist/<int:id>",views.addwatchlist,name="addwatchlist"),path("removewatchlist/<int:id>",views.removewatchlist,name="removewatchlist")

添加/删除”按钮托管在listing.html上:

{% if user.is_authenticated %}
        <p>
            {% if watchlisted %}
            <a href="{% url 'removewatchlist' item.id %}"><button class="btn btn-danger">Remove from watchlist</button></a>
            {% else %}
            <a href="{% url 'addwatchlist' item.id %}"><button class="btn btn-success">Add to watchlist</button></a>
            {% endif %}
          </p>
    {% endif %}

问题:

  • 我将Watchlist.watchlist_listingid用作 上市的外键?我看过很多其他的帖子 人们倾向于完全不使用外键,尽管我相信 可能没有优化。
  • 我最终可能会使用一种表格来包裹那些按钮,但是我 我的listing.html页面中已经有一个表格(用于添加评论)。 尽管我还没有解决从表单处理数据的问题,但可能更容易 设法找出如何在上实现几种不同的Django形式 一个HTML页面。您认为最佳做法是什么?表格或直接 链接召唤功能
  • 对于“添加到监视列表”,为什么我获得def __str__(self):return f'"{self.title}"'而不是简单地在我的列表中添加新条目 监视列表?
  • 最后,对于“从监视列表中删除”,为什么我在我的示例中知道以下事实,为什么收到"id attribute is set to None" “ Iphone 11 Pro”的Listing.id为1,从技术上讲, Watchlist.id(在我的模型中完全不显示)基于11 Django Admin页面。甚至硬编码11也可以强制删除 监视表仍然返回此“无”错误

期待您的回复

解决方法

根据您的特定错误,问题出在这一行,应从错误消息中清除:

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

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

这就是为什么该错误告诉您“ field id”(它需要一个整数)却得到“

“的原因-这是您的Listing模型的实际实例。

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

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

那应该可以解决您的特定问题;话虽如此,但我强烈建议您对这些按钮使用表格。当前,您允许以不安全的方式修改数据库的内容。任何修改数据库内容的活动都应作为POST请求提供。即使您没有使用任何实际的输入字段,也可以很轻松地使用表单来完成此操作。该按钮将作为POST请求提交空表单,您可以在模板的form标记中包含一个csrf令牌,并且数据库将被相应地修改。如果您真的不想使用表单,则另一个选择是使用AJAX调用(通过jQuery),该调用可以作为POST请求发送而无需使用表单。解释如何执行此操作超出了此响应的范围,但是关于SO的信息很多。

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

,

修复以下问题:“字段'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属性设置为“无”。

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中触发特殊功能。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。