Менеджер недоступен через экземпляры WatchList Как исправить эту ошибку?

Я пытаюсь создать сайт электронной коммерции (CS50 Project 2) с помощью Django и имею представление Django с несколькими формами. В этом представлении я пытаюсь использовать булево поле в форме Django, чтобы пользователь мог добавить объявление в свой список просмотра, оба из которых являются моделями. При попытке сделать это я получаю приведенную выше ошибку.

часть файла views.py

def listing(request, id):
    #gets listing
    listing = Listings.objects.get(id=id)
    watchlist_form = WatchListForm()
    if request.method == "POST":
        watchlist_form = WatchListForm(request.POST)
        if watchlist_form.is_valid():
            watchlist = watchlist_form.save(commit=False)
            watchlist.user = request.user
            watchlist.add_to_watchlist = True
            new_watchlist_listing = watchlist.objects.listings.add(listing) 
            return render(request, "auctions/listing.html",{
                "auction_listing": listing,
                "watchlistForm": watchlist_form
            })
        else:
            return render(request, "auctions/listing.html",{
                "auction_listing": listing,
                "form": comment_form,
                "comments": comment_obj,
                "bidForm": bid_form,
                "bids": bid_obj,
                "watchlistForm": watchlist_form
            })
    return render(request, "auctions/listing.html",{
        "auction_listing": listing,
        "form": comment_form,
        "comments": comment_obj,
        "bidForm": bid_form,
        "bids": bid_obj,
        "watchlistForm": watchlist_form
    })

models.py

class Listings(models.Model):
    CATEGORY = [
    ("Miscellaneous", "Miscellaneous"),
    ("Movies and Television", "Movies and Television"),
    ("Sports", "Sports"),
    ("Arts and Crafts", "Arts and Crafts"),
    ("Clothing", "Clothing"),
    ("Books", "Books"),
]
    title = models.CharField(max_length=64)
    description = models.CharField(max_length=500)
    bid = models.DecimalField(max_digits=1000000000000, decimal_places=2)
    image = models.URLField(null=True, blank=True)
    category = models.CharField(max_length=64, choices=CATEGORY, default=None)
    user = models.ForeignKey(User, on_delete=models.CASCADE, default="")


class WatchList(models.Model):
    listings = models.ManyToManyField(Listings)
    user = models.ForeignKey(User, on_delete=models.CASCADE, default="")
    add_to_watchlist = models.BooleanField(default=False)

сообщение об ошибке

raise AttributeError("Manager isn't accessible via %s instances" % cls.__name__)
AttributeError: Manager isn't accessible via WatchList instances

Эта ошибка возникает из-за этой строки: new_watchlist_listing = watchlist.objects.listings.add(listing).

Вы добавляете элементы с помощью modelobject.manytomanyfield.add(), то есть без части .objects. Таким образом, ваше представление должно выглядеть следующим образом:

from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404, redirect

@login_required
def listing(request, id):
    listing = get_object_or_404(Listings.objects, pk=id)
    watchlist_form = WatchListForm()
    if request.method == "POST":
        watchlist_form = WatchListForm(request.POST)
        if watchlist_form.is_valid():
            form.instance.user = request.user
            form.instance.add_to_watchlist = True
            watchlist = form.save()
            watchlist.listings.add(listing)
            return redirect('name-of-the-view')
    return render(request, 'auctions/listing.html',{
        'auction_listing': listing,
        'form': comment_form,
        'comments': comment_obj,
        'bidForm': bid_form,
        'bids': bid_obj,
        'watchlistForm': watchlist_form
    })

Note: It is often better to use get_object_or_404(…) [Django-doc], then to use .get(…) [Django-doc] directly. In case the object does not exists, for example because the user altered the URL themselves, the get_object_or_404(…) will result in returning a HTTP 404 Not Found response, whereas using .get(…) will result in a HTTP 500 Server Error.


Note: In case of a successful POST request, you should make a redirect [Django-doc] to implement the Post/Redirect/Get pattern [wiki]. This avoids that you make the same POST request when the user refreshes the browser.


Note: You can limit views to a view to authenticated users with the @login_required decorator [Django-doc].


Note: Usually it is better not to work with commit=False when saving the form with the .save(…) method [Django-doc]: this will revent saving many-to-many relations since these can only be saved if the item is committed. Usually it is better to alter the .instance wrapped in the form. For more information, see my article[Django-antippaterns] on this.

Вернуться на верх