gpt4 book ai didi

django - 如何在不使用 ModelForm 的情况下验证/清理()unique=True 字段?

转载 作者:行者123 更新时间:2023-12-04 00:53:46 25 4
gpt4 key购买 nike

在自定义表单中,如何验证模型字段的唯一性(即设置了 unique=True)?

我知道 django 的 ModelForm 会自动执行 validate_unique()在 BaseModelForm 的 clean() 中调用的函数方法——因此,当使用 ModelForm 时,这将被正确处理(就像在 Admin 中一样)。

但是,我正在从头开始创建自己的表单,想知道如何自己处理这个问题?我认为我最大的绊脚石是知道在清理数据时哪个对象附加到表单......

一些代码:

class UserProfile(CreatedModifiedModel):
user = models.ForeignKey(User, unique=True)
display_name = models.CharField('Display Name',max_length=30,
blank=True,unique=True)

class EditUserProfileForm(forms.Form):
display_name = forms.CharField(required=False,max_length=30)

# "notifications" are created from a different model, not the UserProfile
notifications = forms.MultipleChoiceField(
label="Email Notifications",
required=False,
widget=forms.CheckboxSelectMultiple,)

def clean_display_name(self):
# how do I run my own validate_unique() on this form?
# how do I know which UserProfile object I am working with?

# more code follows, including the __init__ which sets up the notifications

最佳答案

唯一验证很难完全正确,因此我建议无论如何使用 ModelForm:

class EditUserProfileForm(forms.ModelForm):
# "notifications" are created from a different model, not the UserProfile
notifications = forms.MultipleChoiceField(
label="Email Notifications",
required=False,
widget=forms.CheckboxSelectMultiple,)

class Meta:
model = UserProfile
fields = ('display_name',)

从多个模型制作表单并不容易,但在这种情况下,您只需添加 notifications字段到 ModelForm 并将其拉出 .cleaned_data照常:
# view
if request.method == 'POST':
form = EditUserProfileForm(request.POST, instance=user_profile)
if form.is_valid():
user_profile = form.save()
notifications = form.cleaned_data['notifications']
# Do something with notifications.

我就是这样做的,但是如果您开始验证自己的独特性,您可以随时执行以下操作:
def clean_display_name(self):
display_name = self.cleaned_data['display_name']
if UserProfile.objects.filter(display_name=display_name).count() > 0:
raise ValidationError('This display name is already in use.')
return display_name

我在这里看到有两个问题。首先,您可能会遇到并发问题,即两个人提交相同的名称,都通过了唯一性检查,但随后一个人收到了 DB 错误。另一个问题是您无法编辑用户个人资料,因为您没有要从搜索中排除的 ID。您必须将其存储在您的 __init__ 中然后在清洁中使用它:
def __init__(self, *args, **kwargs):
...
if 'instance' in kwargs:
self.id = kwargs['instance'].id
...

def clean_display_name(self):
display_name = self.cleaned_data['display_name']
qs = UserProfile.objects.filter(display_name=display_name)
if self.id:
qs = qs.exclude(pk=self.id)
if qs.count() > 0:
raise ValidationError('This display name is already in use.')
return display_name

但此时您只是在复制 ModelForms 中的逻辑。

关于django - 如何在不使用 ModelForm 的情况下验证/清理()unique=True 字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1557479/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com