首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Django表单错误: django.db.utils.IntegrityError:唯一约束失败: legal_useragreedtolegal.user_id

Django表单错误: django.db.utils.IntegrityError:唯一约束失败: legal_useragreedtolegal.user_id
EN

Stack Overflow用户
提问于 2021-12-19 09:47:56
回答 2查看 1.5K关注 0票数 2

每当我调用"django.db.utils.IntegrityError:()时,我都会得到失败的legal_useragreedtolegal.user_id“唯一约束:legal_useragreedtolegal.user_id”

我认为这可能是因为我有一个oneToOneField,Django试图保存到UserAgreedToLegal和用户模型,但是用户模型已经有了这个ID,所以唯一的约束失败了,但不确定。

我在想如何解决这个问题。我在下面列出了我的模型、表单和视图代码

models.py

代码语言:javascript
运行
复制
import uuid

from django.contrib.auth.models import User
from django.db import models
from django.utils import timezone as django_timezone


class UserAgreedToLegal(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    agreed_first_terms_of_service = models.BooleanField(default=False, blank=False, null=False)
    date_agreed = models.DateField(null=True, default=django_timezone.now)
    uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)

    def __str__(self):
        return self.user.username

forms.py

代码语言:javascript
运行
复制
from django import forms

from legal.models import UserAgreedToLegal


class TermsOfServiceAgreementForm(forms.ModelForm):
    class Meta:
        model = UserAgreedToLegal
        fields = [
            'agreed_first_terms_of_service'
        ]

views.py

代码语言:javascript
运行
复制
    if request.method == 'POST':
        form = TermsOfServiceAgreementForm(request.POST)
        if form.is_valid():
            form.clean()
            terms_of_service_agreement = form.save(commit=False)
            terms_of_service_agreement.user = request.user

            terms_of_service_agreement.save()

结果是

代码语言:javascript
运行
复制
django.db.utils.IntegrityError: UNIQUE constraint failed: legal_useragreedtolegal.user_id
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-12-29 02:38:14

它失败的原因是因为与django用户模型存在OneToOne关系,当我调用form.save()时,它试图将一个新行(插入一个新用户)保存到用户和我的模型中,然后它会发现这个user_id已经存在于我的模型中,它会告诉我不能这样做,因为这样做违反了我设置的只有一对一关系的规则,因为如果它确实保存了每个用户的许多记录。这将创造一对多,而不是一对一。

相反,我需要做的是告诉django,我不想在我的模型中插入一个新的记录,或者更新它如果该记录已经存在,如果没有创建它,同时维护它与用户模型的关系。

为了知道我已经有了这个模型,我必须传入Django表单的一个实例,并且我不想更新这个实例。

这是对我有用的代码

代码语言:javascript
运行
复制
if request.method == 'POST':
    my_user = UserAgreedToLegal.objects.get_or_create(user=request.user)[0]
    form = TermsOfServiceAgreementForm(request.POST, instance=my_user)

    if form.is_valid():
        form.clean()
        terms = form.save(commit=False)
        terms.user = request.user
        terms.save()
票数 0
EN

Stack Overflow用户

发布于 2021-12-19 10:30:26

--我认为这可能是因为我有一个OneToOneField,而Django试图保存到UserAgreedToLegal和User Model,但是用户模型已经有了这个ID,所以唯一的约束失败了,但不确定。

您是对的,OneToOneField本质上是一个带有unique=TrueForeignKey。因此,第二次访问这一观点是没有意义的。

您可以检查这个人是否已经同意了法律条款,如果是这样的话,可以重定向到一个页面,例如一个视图,该视图呈现一个页面来解释用户已经同意的内容,所以如下所示:

代码语言:javascript
运行
复制
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect

@login_required
def my_view(request):
    if UserAgreedToLegal.objects.filter(user=request.user).exists():
        return redirect('name-of-some-view')
    if request.method == 'POST':
        # …
    # …

其中,name-of-some-view应该指向将呈现该页面的视图。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70410340

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档