【问题标题】:get_or_create throws Integrity Errorget_or_create 抛出完整性错误
【发布时间】:2013-10-22 03:04:01
【问题描述】:

鉴于 object.get_or_create() 的全部意义在于获取对象(如果它已经存在),我不明白为什么它会为此代码引发完整性错误:

class UserAdd(TemplateView):

def post(self, request, *args, **kwargs):
    context = self.get_context_data(*args, **kwargs)
    form = UserAddForm(request.POST)
    if form.is_valid():
        first_name = form.cleaned_data['first_name']
        last_name = form.cleaned_data['last_name']
        myemail = form.cleaned_data['email']
        mypass = form.cleaned_data['password']
        if myemail and mypass:
            myuser,created = User.objects.get_or_create(email=myemail, username=myemail, first_name=first_name, last_name=last_name)
            if created:
                myuser.set_password(mypass)
    return HttpResponseRedirect('/')

这是错误:

django.db.utils.IntegrityError IntegrityError: (1062, "Duplicate entry 'user@domain.com' for key 'username_UNIQUE'")

有人知道怎么回事吗?

【问题讨论】:

  • 一个用户存在这个用户名,但没有这些名字、姓氏或电子邮件。

标签: python django django-forms


【解决方案1】:

我在重新定义模型的save() 方法后遇到了类似的错误。事实证明,如果您在模型中多次调用save,则所有后续调用都应使用force_insert=True 关键字参数进行。在我的情况下,我必须在第二次调用时将 self.save(*args, **kwargs) 更改为 self.save() 以消除错误。 更多详情请阅读:https://code.djangoproject.com/ticket/28253

【讨论】:

    【解决方案2】:

    发送到get_or_create 方法的参数需要完全匹配,否则 django 的 ORM 会尝试创建一个新对象,并且由于会违反主键/唯一列约束,因此您会收到错误消息。

    试试这个:

    if form.is_valid():
        first_name = form.cleaned_data['first_name']
        last_name = form.cleaned_data['last_name']
        myemail = form.cleaned_data['email']
        mypass = form.cleaned_data['password']
        if myemail and mypass:
            myuser,created = User.objects.get_or_create(email=myemail, defaults = {'username': myemail, 'first_name': first_name, 'last_name': last_name})
            if created:
                myuser.set_password(mypass)
    
    return HttpResponseRedirect('/')
    

    get_or_create here 上阅读更多信息。 defaults= 参数是您所需要的。

    【讨论】:

    • 密码不能默认吗?
    • 不,因为set_password 会散列密码并将其存储在数据库中。这是正确的做法。
    • 对。在 set_password 之后我还需要 myuser.save()
    【解决方案3】:

    您要求 django 根据四个条件获取记录:

    • 电子邮件
    • 用户名
    • 名字
    • 姓氏

    所以所有四个字段组合在一起没有记录。

    你应该这样做:

    myuser, created = User.objects.get_or_create(
       username=myemail, defaults={'first_name': first_name, 'last_name': last_name, 'email': myemail})
    

    【讨论】:

    • 这个答案不正确。如果没有记录, get_or_create 会创建它。这就是 get_or_create 的用途,并且用户已经在使用它。由于唯一约束失败而显示 IntegrityError。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    • 2021-09-27
    • 1970-01-01
    • 2016-10-03
    • 2016-04-10
    • 2022-12-21
    • 2013-03-18
    相关资源
    最近更新 更多