Django Adding Values to ForeignKey

14,585

Solution 1

z.watchlist is the reference itself, it is not a relationship manager. Just assign:

z.watchlist = WatchList.objects.get(user__name='SomeUser')

Note that this assumes there is only one WatchList per user.

Solution 2

As karthikr said you may be getting confused with manytomanyfield, if you really want an intermediary model, you might have something like this:

# Models:
class WatchList(models.Model):
    user = models.ForeignKey(User, related_name='watchlists')

class Thing(models.Model):
    watchlist = models.ForeignKey(WatchList, null=True, blank=True)

# Usage:
user = User.objects.get(name='???') # or obtain the user however you like
wl = WatchList.objects.create(user=user)
thing = Thing.objects.get(id=1) # or whatever
thing.watchlist = wl
thing.save()

# get users watch lists:
user.watchlists
...

Otherwise you might want to extend the user model.

Share:
14,585

Related videos on Youtube

Nick B
Author by

Nick B

Updated on May 25, 2022

Comments

  • Nick B
    Nick B about 2 years

    I'm trying to set up a way for users to "watch" certain items (i.e. add items to a list containing other items by other users):

    class WatchList(models.Model):
        user = models.ForeignKey(User)
    
    class Thing(models.Model):
        watchlist = models.ForeignKey(WatchList, null=True, blank=True)
    

    How do I add a Thing to a users WatchList?

    >>> from myapp.models import Thing
    >>> z = get_object_or_404(Thing, pk=1)
    >>> a = z.watchlist.add(user="SomeUser")
    
      AttributeError: 'NoneType' object has no attribute 'add'
    

    How can I add the item to the watchlist? And/or is this the appropriate way to set up my model fields? Thanks for any ideas!

    • karthikr
      karthikr over 10 years
      I think you are getting confused with manytomany. You would just do =
    • Martijn Pieters
      Martijn Pieters over 10 years
      Why not relate directly to the user? Or did you want to create multiple watchlists per user?
    • Nick B
      Nick B over 10 years
      If ultimately Im trying to query to get all the Things that are being watched by a particular User, should I set up my models differently? Would it be better to place a ForeignKey from WatchList to Thing, rather than the way I described above? The ultimate goal is to query to find all things being watched by a particular user...
  • Nick B
    Nick B over 10 years
    Hmm okay that makes a little more sense. How would I then query to find all items that a user is watching?
  • SColvin
    SColvin over 10 years
    explanation added to my answer.
  • Nick B
    Nick B over 10 years
    Ok that makes sense, but I receive an AttributeError: 'User' object has no attribute 'watchlist'. Any ideas why?
  • Nick B
    Nick B over 10 years
    Ok thanks for your input but I am still pretty confused. Maybe I have set up my models wrong. If I want to be able to query to get all Things that a User is Watching, should I use a ManyToMany relationship instead? I also want to be able to get all Users that are Watching a certain Thing.. Sorry for the confusion on my part, but I appreciate your ideas!
  • Martijn Pieters
    Martijn Pieters over 10 years
    Your user object has a .watchlist_set manager; user.watchlist_set.get().thing_set.all() would be all things a user is watching.
  • SColvin
    SColvin over 10 years
    the related name was 'watchlists' not 'watchlist'
  • Nick B
    Nick B over 10 years
    I put that exact code into my python interpreter. With the models defined above, this code: >>> user.watchlists results in AttributeError: 'User' object has no attribute 'watchlists'. The same thing for user.watchlist. What am I missing? Thanks for any ideas!
  • Nick B
    Nick B over 10 years
    Ok well now Im super confused now. Trying z.watchlist = WatchList.objects.filter(user__username='SomeDude') has resulted in a ValueError: Cannot assign "[<WatchList: WatchList object>, <WatchList: WatchList object>, <WatchList: WatchList object>, <WatchList: WatchList object>]": "Thing.watchlist" must be a "WatchList" instance.
  • Martijn Pieters
    Martijn Pieters over 10 years
    @NickB: That is a list of WatchList objects, your user has multiple. Get just one instead; WatchList.objects.filter(user__username='SomeDude')[0] would be the first matching watchlist.
  • Nick B
    Nick B over 10 years
    Ok well I think I may have a problem with the way I setup my models, in that case. What I am hoping to achieve is to query for: Thing.objects.filter(watchlist__user__username='SomeDude') so that I can get all things that a user is watching. Have I set up my models incorrectly in that case? Sorry for the confusion on my part..
  • Nick B
    Nick B over 10 years
    Oh wait actually I just realized that that query worked! Sometimes I guess stumbling through a problem leads to the answer! Thanks for your assistance, apologies for my oversight!
  • Martijn Pieters
    Martijn Pieters over 10 years
    Glad to have been of help!