每当我调用"django.db.utils.IntegrityError:()时,我都会得到失败的legal_useragreedtolegal.user_id“唯一约束: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.usernameforms.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发布于 2021-12-29 02:38:14
它失败的原因是因为与django用户模型存在OneToOne关系,当我调用form.save()时,它试图将一个新行(插入一个新用户)保存到用户和我的模型中,然后它会发现这个user_id已经存在于我的模型中,它会告诉我不能这样做,因为这样做违反了我设置的只有一对一关系的规则,因为如果它确实保存了每个用户的许多记录。这将创造一对多,而不是一对一。
相反,我需要做的是告诉django,我不想在我的模型中插入一个新的记录,或者更新它如果该记录已经存在,如果没有创建它,同时维护它与用户模型的关系。
为了知道我已经有了这个模型,我必须传入Django表单的一个实例,并且我不想更新这个实例。
这是对我有用的代码
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()发布于 2021-12-19 10:30:26
--我认为这可能是因为我有一个
OneToOneField,而Django试图保存到UserAgreedToLegal和User Model,但是用户模型已经有了这个ID,所以唯一的约束失败了,但不确定。
您是对的,OneToOneField本质上是一个带有unique=True的ForeignKey。因此,第二次访问这一观点是没有意义的。
您可以检查这个人是否已经同意了法律条款,如果是这样的话,可以重定向到一个页面,例如一个视图,该视图呈现一个页面来解释用户已经同意的内容,所以如下所示:
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应该指向将呈现该页面的视图。
https://stackoverflow.com/questions/70410340
复制相似问题