Skip to content
Advertisement

create() populates manytomany with every row in the related table, rather than leave it blank [closed]

Currently, I have three models in models.py:

class User(AbstractUser):
    pass 

class Watchlist(models.Model):
    user = models.OneToOneField(User, on_delete = models.CASCADE)
    listings = models.ManyToManyField('Listing', related_name = "watchlists", blank = True)

class Listing(models.Model):
    title = models.CharField(max_length = 150)
    description = models.TextField()

The problem occurs when a user creates their watchlist, which is handled by this piece of code in views.py:

# Each listing has it's own page,
# with a URL of the form /listing/<int:pk> 
def listing(request, pk):
    listing_instance = Listing.objects.get(pk = pk)
    
    if request.method == "GET":
         # return the page for the listing with primary key pk

    elif request.user.is_authenticated:   
        watchlist_instance = Watchlist.objects.get_or_create(user = request.user)[0]
        watchlist_instance.listings.add(listing_instance)

I would expect the row created by Watchlist.objects.get_or_create(user = request.user) to have no relations in its listings, but instead it has relations to every row in the Listing table (meaning the last line does nothing).

For example, if the Listing table contained three rows:

  • listing1
  • listing2
  • listing3

and a new user viewed the page for listing2 and tried to add it to their watchlist, their watchlist would include all three listings.

To confirm it was create() that was causing the problem, I tried this:

    elif request.user.is_authenticated:
        watchlist_instance = listing_instance.watchlists.create(user = request.user)

which looks (to me) to be basically equivalent to the example given in the official docs for create(), but has the same problem as my other code.

How can I ensure that create() leaves listings blank (so that I can then add the single listing_instance to it), rather than populating it with every listing in the table?

Edit: The problem persists even when creating the watchlist in Django’s admin interface; the field is automatically populated with every listing. Also, there is no way to remove the relations, either by clear(), remove() or in the admin interface.

Django version 3.1.1

sqlite3

python 3.8.6

Advertisement

Answer

OP is an idiot, this problem never existed.

I assumed that Django’s admin page for a watchlist would only show the listings that were related, but it turns out it just shows every listing whether they’re related or not.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement