django get_or_create and manytomanyfield

  • Last Update :
  • Techknowledgy :
def phone_request(request):
   user_id = request.user.id
uuid = request.GET.get('uuid')
profile_id = profiles.objects.get(uuid = uuid).user_id
p, created = Photo_request_list.objects.get_or_create(who = user_id)
p.whose.add(profiles.objects.get(uuid = uuid))
p.save()

Suggestion : 2

In this example, an Article can be published in multiple Publication objects, and a Publication has multiple Article objects:,To define a many-to-many relationship, use ManyToManyField., Django 4.0 documentation Using Django Models and databases Examples of model relationship API usage Many-to-many relationships ,Using Django Models and databases Examples of model relationship API usage Many-to-many relationships

from django.db
import models

class Publication(models.Model):
   title = models.CharField(max_length = 30)

class Meta:
   ordering = ['title']

def __str__(self):
   return self.title

class Article(models.Model):
   headline = models.CharField(max_length = 100)
publications = models.ManyToManyField(Publication)

class Meta:
   ordering = ['headline']

def __str__(self):
   return self.headline
>>> p1 = Publication(title = 'The Python Journal') >>>
   p1.save() >>>
   p2 = Publication(title = 'Science News') >>>
   p2.save() >>>
   p3 = Publication(title = 'Science Weekly') >>>
   p3.save()
>>> a1 = Article(headline = 'Django lets you build web apps easily')
>>> a1.publications.add(p1)
Traceback (most recent call last):
...
ValueError: "<Article: Django lets you build web apps easily>" needs to have a value for field "id" before this many-to-many relationship can be used.
>>> a1.save()
>>> a1.publications.add(p1)

Suggestion : 3

Using get_or_create through a ManyToMany field results in an integrity error if the object being queried for already exists but is not yet associated with the parent object: , To summarize, if a Tag with text 'foo' exists but is not yet associated with a given Thing instance, using .tags.get_or_create(text='foo') raises an IntegrityError since it tries to re-create the same Tag. , Fixes #18896. Add tests verifying that you can get IntegrityErrors using get_or_create through relations like M2M, and it also adds a note into the documentation warning about it , Marking this DDN. Although I see your point and the solution seems reasonable to me, this seems like it could be more of a new feature than a bug - but I'm not sure.

Using get_or_create through a ManyToMany field results in an integrity error if the object being queried for already exists but is not yet associated with the parent object:

class Tag(models.Model):
text = models.CharField(max_length=256, unique=True)

class Thing(models.Model):
name = models.CharField(max_length=256)
tags = models.ManyToManyField(Tag)

#create and save a Tag
Tag.objects.create(text='foo')

#create and save a Thing
a_thing = Thing.objects.create(name='a')

#get the previously created Tag and have it associated with a_thing
a_thing.tags.get_or_create(text='foo') #should get

Traceback (most recent call last):
File "<input>", line 1, in <module>
   File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/related.py", line 616, in get_or_create
   super(ManyRelatedManager, self.db_manager(db)).get_or_create(**kwargs)
   File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 134, in get_or_create
   return self.get_query_set().get_or_create(**kwargs)
   File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 449, in get_or_create
   obj.save(force_insert=True, using=self.db)
   File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 463, in save
   self.save_base(using=using, force_insert=force_insert, force_update=force_update)
   File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 551, in save_base
   result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
   File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 203, in _insert
   return insert_query(self.model, objs, fields, **kwargs)
   File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 1576, in insert_query
   return query.get_compiler(using=using).execute_sql(return_id)
   File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 910, in execute_sql
   cursor.execute(sql, params)
   File "/usr/local/lib/python2.7/dist-packages/django/db/backends/util.py", line 40, in execute
   return self.cursor.execute(sql, params)
   File "/usr/local/lib/python2.7/dist-packages/django/db/backends/sqlite3/base.py", line 337, in execute
   return Database.Cursor.execute(self, query, params)
   IntegrityError: column text is not unique

Suggestion : 4

You can use Django get_or_create with ManyToMany fields like so:,It’s a convenient way to avoid boilerplate get and create code,Django get_or_create returns the object that it got and a boolean value that specifies whether the object was created or not. If get_or_create finds multiple objects it will raise a MultipleObjectsReturned exception.,Django get_or_create on the other hand is atomic (assuming everything is configured correctly, more on that below), meaning that it’s a single operation and so can be used concurrently. Here’s how to use it:

Here’s how you would usually deal with get/create:

try:
author = Author.objects.get(name = 'Leo Tolstoy')
except DoesNotExist:
   author = Author(name = 'Leo Tolstoy')
author.save()

# Do something with author

Django get_or_create on the other hand is atomic (assuming everything is configured correctly, more on that below), meaning that it’s a single operation and so can be used concurrently. Here’s how to use it:

author, created = Author.objects.get_or_create(name = 'Leo Tolstoy')
# Do something with author

That’s why to guarantee an atomic transaction, there has to be a uniqueness constraint on the fields you are querying for. For example, this will potentially create duplicates and isn’t safe:

class Author(models.Model):
   first_name = models.CharField(max_length = 255)
last_name = models.CharField(max_length = 255)

author, created = Author.objects.get_or_create(first_name = 'Leo', last_name = 'Tolstoy')

You can pass a defaults argument to get_or_create that will only be used in the create portion of the query:

author, created = Author.objects.get_or_create(name = 'Leo Tolstoy', defaults = {
   'books_in_store': 0,
   'store': 'Amazon'
})

You can have more complex queries using filters and Q objects

author, created = Author.objects.filter(
   Q(name = 'John Smith') | Q(name = 'Leo Tolstoy')
).get_or_create(name = 'Leo Tolstoy')

Suggestion : 5

1. How to create multiple objects in one shot?,There are conditions when we want to save multiple objects in one go. Say we want to add multiple categories at once and we don’t want to make many queries to the database. We can use bulk_create for creating multiple objects in one shot.,13. How to add multiple databases to the django application ?, Read more books at https://books.agiliq.com

>>> Category.objects.all().count()
2
>>> Category.objects.bulk_create(
[Category(name="God"),
Category(name="Demi God"),
Category(name="Mortal")]
)
[<Category: God>, <Category: Demi God>, <Category: Mortal>]
         >>> Category.objects.all().count()
         5