С 2013 года или около того, get_or_create атомная, поэтому он обрабатывает параллелизм красиво:
Этот метод является атомарным при условии правильного использования, правильная база данных конфигурации, и правильное поведение базовой базы данных. Однако, если уникальность не применяется на уровне базы данных для kwargs, используемых в вызове get_or_create (см. Уникальный или unique_together), этот метод подвержен условию гонки, которое может привести к нескольким строкам с теми же параметрами, что и вставлен одновременно.
Если вы используете MySQL, не забудьте использовать READ COMMITTED изоляции уровня, а не REPEATABLE READ (по умолчанию), в противном случае вы можете увидеть случаи, когда get_or_create возбудит IntegrityError но объект не появится последующий вызов get().
От: https://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create
Вот пример того, как вы могли бы сделать это:
Определить модель либо уникальный = 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>})
... или с помощью 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>})
Обратите внимание, как не уникальные поля находятся в файле dict по умолчанию, а не в уникальных полях в get_or_create. Это гарантирует, что ваши создания будут атомарными.
Вот как это реализовано в Django: https://github.com/django/django/blob/fd60e6c8878986a102f0125d9cdf61c717605cf1/django/db/models/query.py#L466 - Попробуйте создать объект, поймайте возможное IntegrityError и верните копию в этом случае. Другими словами: обрабатывать атомарность в базе данных.
Один из двух потоков получит дублируемую ошибку записи и исключение. Не будет дублированных данных. –