如果不存在则使用atomic()Django创建对象

时间:2016-12-05 10:26:00

标签: django django-models

    a = self.request['a']
    b = self.request['b']

    with atomic('core'):
        obj_qs = Demo.objects.filter(field_a=a, field_b=b)
        if obj_qs.count() > 0:
            raise ValidationError(detail="duplicate not allowed")

        demo = Demo(               
            field_a= a ,
            fields_b = b,
            name = name,
            desc = desc
        )
        demo.save()

    return demo

我尝试确保没有创建重复的对象,但即使它在原子函数中验证失败并且重复值创建

这意味着我得到了2个包含field_a和field_2且具有相同值的演示对象,保存和检查的值是相同的

任何想法??

3 个答案:

答案 0 :(得分:3)

你也可以试试这个,

try:
    obj = Demo.objects.get(field_a='a', field_b='b')
except Demo.DoesNotExist:
    obj = Demo(field_a=a, field_b=b, name=name,desc=desc)
    obj.save()

您还有其他一些解决方案 -

答案 1 :(得分:1)

我一直在寻找一种解决方法,上面的答案是可以找到的,但是文档中所述的简化版本是

obj, created = Person.objects.update_or_create(
    first_name='John', last_name='Lennon',
    defaults={'first_name': 'Bob'},
)

更好,更清洁

答案 2 :(得分:0)

Django已经内置了这个:get_or_create

  

这个方法是原子假设正确使用,正确的数据库   配置和底层数据库的正确行为。   但是,如果未在数据库级别强制执行唯一性   在get_or_create调用中使用的kwargs(请参阅unique或unique_together),   这种方法容易出现竞争条件,可能导致多重竞争   同时插入具有相同参数的行。

仔细注意是否需要唯一索引。使用get_or_create或您当前的方法,如果您没有它们,都将失败。