Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Adding model to ManyToMany by pk, without fetching

Tags:

python

orm

django

I have model A with a ManyToMany to model B. I have a pk of an object of model B, and I want to add it to the ManyToManyField of an object of model A. Is it possible to add it without expending resources to fetch object b from the database? I already have its pk, can I add it without fetching?

like image 843
Ram Rachum Avatar asked Mar 23 '14 18:03

Ram Rachum


1 Answers

You can use add(). Django knows that if it's a number instead of an object, to treat it as a primary key:

class Foo(models.Model):
    bars = models.ManyToMany('Bar')

class Bar(models.Model):
    ...


>>> foo = Foo.objects.latest('id') #arbitrary
>>> target_pk = 5
>>> 
>>> # method 1:
>>> bar = Bar.objects.get(pk=target_pk)
>>> foo.bars.add(bar)
>>>
>>> # method 2:
>>> foo.bars.add(target_pk) # will work just the same

target_pk can also be a string. If you want to add a list of primary keys, you'll have to pass them as arguments, thusly:

>>> pk_list = [1, 2, 3]
>>> foo.bars.add(*pk_list)

This will also work if the items would be strings, i.e. pk_list = ['1', '2', '3']. Just remember that if one of the pks is for an object already related you'll get a UNIQUE constrained failed error

This will even work if the primary key isn't an integer. Say I define a primary key as a CharField with length of 15, and I have an object who's primary key is 'Lorem Ipsum', doing this:

>>> foo.bars.add('Lorem Ipsum')

Will work like a charm!

like image 160
yuvi Avatar answered Sep 19 '22 03:09

yuvi