Từ 2013 hoặc lâu hơn, get_or_create là nguyên tử, vì vậy nó xử lý đồng thời độc đáo:
Phương pháp này là nguyên tử giả sử dụng đúng, chính xác cơ sở dữ liệu cấu hình, và hành vi chính xác của cơ sở dữ liệu bên dưới. Tuy nhiên, nếu tính duy nhất không được thực thi ở cấp cơ sở dữ liệu cho các sốkwarg được sử dụng trong lệnh gọi get_or_create (xem duy nhất hoặc duy nhất_together), phương pháp này dễ bị điều kiện chủng tộc có thể dẫn đến nhiều hàng . được chèn đồng thời.
Nếu bạn đang sử dụng MySQL, hãy chắc chắn để sử dụng ĐỌC CAM KẾT mức cô lập hơn là đọc lặp lại (mặc định), nếu không bạn có thể thấy trường hợp get_or_create sẽ nâng cao một IntegrityError nhưng đối tượng sẽ không xuất hiện trong một cuộc gọi get() tiếp theo.
Từ: https://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create
Dưới đây là một ví dụ về cách bạn có thể làm điều đó:
Xác định một mô hình với một trong hai độc đáo = 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>})
... hoặc bằng cách sử dụng 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>})
Lưu ý cách các trường không phải là duy nhất nằm trong dict mặc định, KHÔNG nằm trong số các trường duy nhất trong get_or_create. Điều này sẽ đảm bảo tạo của bạn là nguyên tử.
Đây là cách nó được triển khai trong Django: https://github.com/django/django/blob/fd60e6c8878986a102f0125d9cdf61c717605cf1/django/db/models/query.py#L466 - Thử tạo đối tượng, nắm bắt một IntegrityError cuối cùng và trả lại bản sao trong trường hợp đó. Nói cách khác: xử lý nguyên tử trong cơ sở dữ liệu.
Một trong hai chủ đề sẽ nhận được lỗi bản ghi trùng lặp và ngoại lệ. Sẽ không có dữ liệu trùng lặp. –