Django form error: django.db.utils.IntegrityError: UNIQUE constraint failed: legal_useragreedtolegal.user_id
Django form error: django.db.utils.IntegrityError: UNIQUE constraint failed: legal_useragreedtolegal.user_id
每当我调用 form.save() 我得到“django.db.utils.IntegrityError: UNIQUE constraint failed: legal_useragreedtolegal.user_id”
我想这可能是因为我有一个 oneToOneField 并且 Django 正在尝试保存到 UserAgreedToLegal 和用户模型,但是用户模型已经有那个 ID,所以唯一约束失败了,但不确定。
我想知道如何解决这个问题。我在下面列出了我的模型、表单和视图代码
models.py
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
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
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()
结果是
django.db.utils.IntegrityError: UNIQUE constraint failed: legal_useragreedtolegal.user_id
I think this might be because I have a OneToOneField
and Django is trying to save to UserAgreedToLegal and User Model but the User model already has that ID, so the unique constraint fails, but not sure.
你是对的,OneToOneField
本质上是 ForeignKey
和 unique=True
。因此,第二次访问该视图毫无意义。
您可以检查此人是否已同意法律条款,如果是,则重定向到页面,例如呈现页面以解释用户已同意的视图,例如:
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('<em>name-of-some-view</em>')
if request.method == 'POST':
# …
# …
其中 name-of-some-view
应指向将呈现该页面的视图。
它失败的原因是因为与 django 用户模型存在 OneToOne 关系,当我调用 form.save() 它试图将新行(插入新用户)保存到两者中用户和我的模型,然后它会看到这个 user_id 已经存在于我的模型中,它会告诉我它不能完成,因为那样它会违反我规定的只有一对一关系的规则,因为如果它确实保存了每个用户将有很多记录。这将创建一对多而不是一对一。
相反,我需要做的是告诉 django 我不想在我的模型中插入新记录,或者如果该记录已经存在则更新它,如果不创建它,同时保持与用户模型。
我必须为 Django Forms 传递一个实例才能知道我已经有了这个模型并且我不想更新这个实例。
这是对我有用的代码
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()
每当我调用 form.save() 我得到“django.db.utils.IntegrityError: UNIQUE constraint failed: legal_useragreedtolegal.user_id”
我想这可能是因为我有一个 oneToOneField 并且 Django 正在尝试保存到 UserAgreedToLegal 和用户模型,但是用户模型已经有那个 ID,所以唯一约束失败了,但不确定。
我想知道如何解决这个问题。我在下面列出了我的模型、表单和视图代码
models.py
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
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
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()
结果是
django.db.utils.IntegrityError: UNIQUE constraint failed: legal_useragreedtolegal.user_id
I think this might be because I have a
OneToOneField
and Django is trying to save to UserAgreedToLegal and User Model but the User model already has that ID, so the unique constraint fails, but not sure.
你是对的,OneToOneField
本质上是 ForeignKey
和 unique=True
。因此,第二次访问该视图毫无意义。
您可以检查此人是否已同意法律条款,如果是,则重定向到页面,例如呈现页面以解释用户已同意的视图,例如:
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('<em>name-of-some-view</em>')
if request.method == 'POST':
# …
# …
其中 name-of-some-view
应指向将呈现该页面的视图。
它失败的原因是因为与 django 用户模型存在 OneToOne 关系,当我调用 form.save() 它试图将新行(插入新用户)保存到两者中用户和我的模型,然后它会看到这个 user_id 已经存在于我的模型中,它会告诉我它不能完成,因为那样它会违反我规定的只有一对一关系的规则,因为如果它确实保存了每个用户将有很多记录。这将创建一对多而不是一对一。
相反,我需要做的是告诉 django 我不想在我的模型中插入新记录,或者如果该记录已经存在则更新它,如果不创建它,同时保持与用户模型。
我必须为 Django Forms 传递一个实例才能知道我已经有了这个模型并且我不想更新这个实例。
这是对我有用的代码
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()