示例代码
假设您有以下模型:
class DictionaryEntry(models.Model):
    name = models.CharField(max_length=255, null=False, blank=False)
    definition = models.TextField(null=True, blank=False)
和以下代码:
obj, created = DictionaryEntry.objects.get_or_create(
    name='apple', definition='some kind of fruit')
get_or_create
如果您还没有看到以下代码get_or_create:
 # simplified
 def get_or_create(cls, **kwargs):
     try:
         instance, created = cls.get(**kwargs), False
     except cls.DoesNotExist:
         instance, created = cls.create(**kwargs), True
     return instance, created
关于网络服务器...
现在想象一下,您有一个带有2工作进程的网络服务器,它们都有自己的数据库并发访问权限。
 # simplified
 def get_or_create(cls, **kwargs):
     try:
         instance, created = cls.get(**kwargs), False # <===== nope not there...
     except cls.DoesNotExist:
         instance, created = cls.create(**kwargs), True
     return instance, created
如果时机正确(或错误,取决于您要如何表达),两个进程都可以进行查找但找不到该项目。他们都可以创建项目。一切都很好...
MultipleObjectsReturned: get() returned more than one KeyValue -- it returned 2!
一切都很好......直到你get_or_create第三次打电话,他们说“第三次是一种魅力”。
 # simplified
 def get_or_create(cls, **kwargs):
     try:
         instance, created = cls.get(**kwargs), False # <==== kaboom, 2 objects.
     except cls.DoesNotExist:
         instance, created = cls.create(**kwargs), True
     return instance, created
unique_together
你怎么能解决这个问题?也许在数据库级别强制执行约束:
class DictionaryEntry(models.Model):
    name = models.CharField(max_length=255, null=False, blank=False)
    definition = models.TextField(null=True, blank=False)
    class Meta:
        unique_together = (('name', 'definition'),)
回到函数:
 # simplified
 def get_or_create(cls, **kwargs):
     try:
         instance, created = cls.get(**kwargs), False
     except cls.DoesNotExist:
         instance, created = cls.create(**kwargs), True # <==== this handles IntegrityError
     return instance, created
假设你和之前有相同的种族,他们都没有找到该项目并继续插入;这样做他们将开始一个事务,其中一个将赢得比赛,而另一个将看到IntegrityError.
mysql?
该示例使用 a TextField,用于mysql转换为 a LONGTEXT(在我的情况下)。添加unique_together约束使syncdb.
  django.db.utils.InternalError: (1170, u"BLOB/TEXT column 'definition' used in key specification without a key length")
所以,没有运气,你可能不得不MultipleObjectsReturned手动处理。
可能的解决方案
- 可以将 替换TextField为CharField。
- 可以添加 a CharField,它可能是 的强散列TextField,您可以pre_save在 a 中计算和使用unique_together。