具有独特字段的 Django UpdateView
Django UpdateView with unique fields
有没有办法在更新视图中更新唯一字段?
我有一个具有 name
和 age
字段的模型,但是当我尝试更新 age
甚至不更改 name
的值时,它 returns数据库中已存在该名称的错误
models.py
class MyModel(models.Model)
name = models.CharField(max_length=200, unique=True)
age = models.IntegerField()
views.py
class MyModelUpdateView(UpdateView):
def get(self):
self.object = self.get_object()
my_model = self.object
form = MyModelForm(instance=my_model)
return self.render_to_response(
self.get_context_data(pk=my_model.pk, form=form)
)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
my_model = self.object
form = MyModelForm(data=request.POST, instance=my_model)
if form.is_valid():
form.save()
return some_url
return self.render_to_response(
self.get_context_data(pk=my_model.pk, form=form)
)
forms.py
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = (
'name',
'age',
)
def clean(self):
cleaned_data = super().clean()
if MyModel.objects.filter(
active=True, name=cleaned_data.get('name')
).exists():
raise forms.ValidationError('MyModel already exists.')
return cleaned_data
我在这里错过了什么?谢谢。
由于您更新了一个模型,并且您没有更改 name
,当然已经存在具有该名称的记录:那个 特定记录。因此,您应该将检查代码更改为:
class MyModelForm(forms.ModelForm):
def clean(self, *args, **kwargs):
cleaned_data = super().clean(*args, **kwargs)
if MyModel.objects.<b>exclude(pk=self.instance.pk)</b>.filter(
active=True, name=cleaned_data.get('name')
).exists():
raise forms.ValidationError('MyModel already exists.')
return cleaned_data
class Meta:
model = MyModel
fields = ('name', 'age')
请不要改变UpdateView
的样板逻辑,您可以通过以下方式轻松实现:
class MyModelUpdateView(UpdateView):
<b>form_class = MyModelForm</b>
success_url = <i>'some url'</i>
也就是说,如果您已经将字段设置为unique=True
,那么就没有必要自己实施检查了。在这里,您似乎已经 拥有 一个 unique=True
约束:
class MyModel(models.Model)
name = models.CharField(max_length=200, <b>unique=True</b>)
age = models.IntegerField()
在那种情况下,您可以简单地让 ModelForm
完成工作,那么您的表单如下所示:
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ('name', 'age')
只有当您想要更复杂的唯一性(例如 active=True
?),并且您不能(轻松地)表示它时,您才应该进行自己的验证。
有没有办法在更新视图中更新唯一字段?
我有一个具有 name
和 age
字段的模型,但是当我尝试更新 age
甚至不更改 name
的值时,它 returns数据库中已存在该名称的错误
models.py
class MyModel(models.Model)
name = models.CharField(max_length=200, unique=True)
age = models.IntegerField()
views.py
class MyModelUpdateView(UpdateView):
def get(self):
self.object = self.get_object()
my_model = self.object
form = MyModelForm(instance=my_model)
return self.render_to_response(
self.get_context_data(pk=my_model.pk, form=form)
)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
my_model = self.object
form = MyModelForm(data=request.POST, instance=my_model)
if form.is_valid():
form.save()
return some_url
return self.render_to_response(
self.get_context_data(pk=my_model.pk, form=form)
)
forms.py
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = (
'name',
'age',
)
def clean(self):
cleaned_data = super().clean()
if MyModel.objects.filter(
active=True, name=cleaned_data.get('name')
).exists():
raise forms.ValidationError('MyModel already exists.')
return cleaned_data
我在这里错过了什么?谢谢。
由于您更新了一个模型,并且您没有更改 name
,当然已经存在具有该名称的记录:那个 特定记录。因此,您应该将检查代码更改为:
class MyModelForm(forms.ModelForm):
def clean(self, *args, **kwargs):
cleaned_data = super().clean(*args, **kwargs)
if MyModel.objects.<b>exclude(pk=self.instance.pk)</b>.filter(
active=True, name=cleaned_data.get('name')
).exists():
raise forms.ValidationError('MyModel already exists.')
return cleaned_data
class Meta:
model = MyModel
fields = ('name', 'age')
请不要改变UpdateView
的样板逻辑,您可以通过以下方式轻松实现:
class MyModelUpdateView(UpdateView):
<b>form_class = MyModelForm</b>
success_url = <i>'some url'</i>
也就是说,如果您已经将字段设置为unique=True
,那么就没有必要自己实施检查了。在这里,您似乎已经 拥有 一个 unique=True
约束:
class MyModel(models.Model)
name = models.CharField(max_length=200, <b>unique=True</b>)
age = models.IntegerField()
在那种情况下,您可以简单地让 ModelForm
完成工作,那么您的表单如下所示:
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ('name', 'age')
只有当您想要更复杂的唯一性(例如 active=True
?),并且您不能(轻松地)表示它时,您才应该进行自己的验证。