简体   繁体   English

/addtowatchlist/5 处的 AttributeError:“QuerySet”object 没有属性“listings”

[英]AttributeError at /addtowatchlist/5: 'QuerySet' object has no attribute 'listings'

Within my app, I'm allowing any given user to add an auction listing to their watch list, but no matter what I have tried, it does not seem to work and I keep getting the error in the title.在我的应用程序中,我允许任何给定用户将拍卖列表添加到他们的监视列表中,但无论我尝试了什么,它似乎都不起作用,而且我一直在标题中收到错误消息。 I am simply trying to access the user thats making the request and adding the listing to their watchlist and redirecting them to the main page.我只是想访问发出请求的用户并将列表添加到他们的监视列表并将他们重定向到主页。

views.py视图.py

from .models import *

def add_to_watchlist(request, listing_id):
    
    listing = Listing.objects.get(id=listing_id)
    # Retrieving the user watchlist (where it always fails)
    watchlist = PersonalWatchList.objects.filter(user=request.user)
    

    # Fails here too
    if (watchlist.listings.all() == None) or (listing not in watchlist.listings.all()):
        watchlist.listings.add(listing)
        watchlist.save()
    else:
        messages.error(request, "Listing is already in your Watchlist.")
        return redirect(reverse('index'))

    messages.success(request, "Listing added to your Watchlist.")
    return redirect(reverse('index'))

models.py模型.py

class PersonalWatchList(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    listings = models.ManyToManyField(Listing, blank=True)

    def __str__(self):
        return f"Watchlist for {self.user}"

urls.py网址.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.createListing, name="create"),
    path("view/<str:listing_title>", views.view, name="view"),
    path("addtowatchlist/<int:listing_id>", views.add_to_watchlist, name="add_to_watchlist")
]

Section of template used to add listing to watchlist用于将列表添加到监视列表的模板部分

<div class="listing-actions">
<a href= {% url 'view' listing.title %} class="btn btn-primary view-button">View</a>
<!--TODO: Make watchlist-->
<a href={% url 'add_to_watchlist' listing.id %} class="btn btn-primary add-to-watchlist-button">Watchlist</a>
</div> 

I have tried changing my logic around using try and except, but it still results in a very similar error.我尝试过使用 try 和 except 改变我的逻辑,但它仍然会导致非常相似的错误。 In my urls.py I have tried changing the path names to avoid them from overlapping, as the "view" and "add_*to_*watchlist" were similar before, but that change still has not worked.在我的 urls.py 中,我尝试更改路径名称以避免它们重叠,因为“view”和“add_*to_*watchlist”之前很相似,但该更改仍然无效。 Before, in之前,在

watchlist = PersonalWatchList.objects.filter(user=request.user)监视列表 = PersonalWatchList.objects.filter(user=request.user)

I used get() instead, and that wasn't working either.我改为使用 get() ,但它也不起作用。 Any tips would be greatly appreciated!任何提示将非常感谢!

Edit: When I add listings to a given users watchlist through django admin, that works just fine, which I really don't understand how, but through the server itself it fails编辑:当我通过 django 管理员将列表添加到给定用户监视列表时,效果很好,我真的不明白如何,但是通过服务器本身它失败了

To retrieve an individual user's watchlist, use get instead of filter:要检索单个用户的监视列表,请使用 get 而不是过滤器:

watchlist = PersonalWatchList.objects.get(user=request.user)

Using the filter() method is returning a QuerySet (Multiple objects) as opposed to the single unique one you want.使用 filter() 方法返回一个 QuerySet(多个对象),而不是您想要的单个唯一对象。

The other issue is in your model definition.另一个问题在您的 model 定义中。 To use the default user class as a foreign key, you need to use要使用默认用户 class 作为外键,您需要使用

turning this:转动这个:

user = models.ForeignKey(User, on_delete=models.CASCADE)

into this:进入这个:

user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

Try this and comment your results.试试这个并评论你的结果。

I essentially had to change up my logic, as I came to understand that the reason this error was being thrown was because the User did not exist yet in the PersonalWatchList Model. Here is the updated workaround.我基本上不得不改变我的逻辑,因为我了解到引发此错误的原因是因为用户在 PersonalWatchList Model 中尚不存在。这是更新的解决方法。

views.py updated views.py 已更新

def add_to_watchlist(request, listing_id):
    user = request.user

    # Getting the listing that was clicked
    listing = Listing.objects.get(id=listing_id)

    # Retrieving the user watchlist (if it exists)
    try:
        watchlist_exists = PersonalWatchList.objects.get(user=request.user)
    except:
        watchlist_exists = None

    # If there isn't one for this user, make one
    if watchlist_exists == None:
        PersonalWatchList.objects.create(user=user)

    # Access that watchlist
    watchlist = PersonalWatchList.objects.get(user=user)

    # Comparing the listings already present in their watchlist to the one that was hit
    if (listing not in watchlist.listings.all()):
        watchlist.listings.add(listing)
        watchlist.save()
    else:
        messages.error(request, "Listing is already in your Watchlist.")
        return redirect(reverse('index'))

    messages.success(request, f"'{listing}' added to your Watchlist.")
    return redirect(reverse('index'))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM