Django unable to add to ManyToMany field in model

I have Listings and Watch models. In Watch.listings is a ManyToManyField for Listings. When I try to add a listing to a watch instance it does not get added and I am getting no errors.

in models.py:

class Listings(models.Model):
    CATEGORY_CHOICES = [
        ("None", "Optional"),
        ("Home", "Home"),
        ("Auto", "Auto"),
        ("Farm", "Farm"),
        ("Recreation", "Recreation"),
        ("Sporting Goods", "Sporting Goods"),
        ("Watercraft", "Watercraft"),
        ("Electronics", "Electronics")
    ]
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    description = models.TextField(max_length=2000)
    photoURL = models.URLField(blank=True)
    category = models.CharField(max_length=15, choices=CATEGORY_CHOICES, blank=True)
    starting_bid = models.DecimalField(max_digits=12, decimal_places=2)
    highest_bid = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)
    date_created = models.DateField(auto_now_add=True)

    def __str__(self):
        return f"User: {self.user}, Listing: {self.title}."

class Watch(models.Model):
    listings = models.ManyToManyField(Listings, related_name="watching", blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return f"{self.user}, watching: {self.listings}"

in views.py:

def get_listing(listing_id):
    try:
        return Listings.objects.get(pk=listing_id)
    except:
        return None

def get_watching(user):
    try:
        return Watch.objects.get(user=user)
    except Watch.DoesNotExist:
        return None

def watch(request, listing_id):
    if request.method == "POST":
        if request.POST["watch"] == "watch":
            listing = get_listing(listing_id)
            if not listing:
                return HttpResponseBadRequest("Bad Request: listing does not exist.")
            
            watching = get_watching(request.user)
            if not watching:
                # save user to watch and add
                print("creating and saving to watch list")
                watch = Watch(user=request.user)
                watch.save()
                # saves no errors
                watch.listings.add(listing)
                # listing not added to watch
                print("watch = ", watch)
                # prints: watch =  Billy, watching: auctions.Listings.None
            else:
                # add to watching
                # subsequent watch attempts
                print("saving to watch list")
                watching.listings.add(listing)
                # listing not added to watching
                print("watching.listings = ", watching.listings)
                # prints: watching.listings =  auctions.Listings.None
            return HttpResponseRedirect(reverse("listing_view", args=(listing.id,)))
        else:
            # unwatch, temporary return
            return HttpResponseRedirect(reverse("index"))
    else:
        return HttpResponseRedirect(reverse("index"))

What does printing watch.listings.all() give you.

1 Like

Many-to-many documentation.

Make sure you save both objects before adding one to the other. Also, you’ll get better help if you can post your project or a working, minimal piece of it that produces the problem on repl.it for easier debugging.

Turns out it is working. I wasn’t getting the queryset properly. watch.listings.all() returns the expected result.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.