Dal 2013 o giù di lì, get_or_create è atomico, in modo che gestisce concorrenza bene:
Questo metodo è atomico assumendo un corretto utilizzo, corretta database di configurazione , e corretto comportamento del database sottostante. Tuttavia, se l'univocità non viene applicata a livello di database per i kwarg utilizzati in una chiamata get_or_create (vedere unique o unique_together), questo metodo è soggetto a una condizione di competizione che può comportare più righe con gli stessi parametri di inserito contemporaneamente.
Se si sta utilizzando MySQL, assicurarsi di utilizzare il READ COMMITTED livello di isolamento piuttosto che REPEATABLE READ (il default), altrimenti si rischia di vedere casi in cui get_or_create alzerà un IntegrityError ma l'oggetto non apparirà in una successiva chiamata get().
Da: https://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create
Ecco un esempio di come si potesse fare:
definire un modello unico nel suo genere sia con = True:
class MyModel(models.Model):
slug = models.SlugField(max_length=255, unique=True)
name = models.CharField(max_length=255)
MyModel.objects.get_or_create(slug=<user_slug_here>, defaults={"name": <user_name_here>})
... o utilizzando unique_togheter :
class MyModel(models.Model):
prefix = models.CharField(max_length=3)
slug = models.SlugField(max_length=255)
name = models.CharField(max_length=255)
class Meta:
unique_together = ("prefix", "slug")
MyModel.objects.get_or_create(prefix=<user_prefix_here>, slug=<user_slug_here>, defaults={"name": <user_name_here>})
Nota come i campi non univoci sono nei valori di default dict, NON tra i campi unici in get_or_create. Questo assicurerà che le tue creazioni siano atomiche.
Ecco come è implementato in Django: https://github.com/django/django/blob/fd60e6c8878986a102f0125d9cdf61c717605cf1/django/db/models/query.py#L466 - Provare a creare un oggetto, prendere un eventuale errore Integrity e restituire la copia in quel caso. In altre parole: gestisci l'atomicità nel database.
Uno dei due thread riceverà un errore di registrazione duplicato e un'eccezione. Non ci saranno dati duplicati. –