我有一个模型,该模型的用户为1个字段(外键),另一个为字段skill_group。我需要确保用户没有添加重复的技能组,所以我添加了UniqueConstraint。这是由于/ skillgroup / create /下的IntegrityError导致系统错误而起作用 重复键值违反唯一约束“ unique_skillgroup”-如何捕获此异常并通知用户是否重复;否则保存吗?
Django / Python / Postgres的新手,我认为我可以通过覆盖save()函数来处理它,但是这是检查的一部分,无法访问用户,我已经读过,这里不应该处理。我应该使用尝试/保存捕获/消息吗?我已经尝试了一些没有运气的事情。我在这里看到过类似的问题,但并没有帮助。任何帮助表示赞赏。
models.py
class SkillGroup(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
skill_group = models.CharField(max_length=35)
sequence = models.IntegerField(default=999)
class Meta:
constraints = [
models.UniqueConstraint(fields=['user', 'skill_group'], name='unique_skillgroup'),
]
def __str__(self):
return self.skill_group
def get_absolute_url(self):
return reverse('skillgroup-list')
views.py
class SkillGroupCreateView(LoginRequiredMixin, CreateView):
model = SkillGroup
fields = ['skill_group']
def form_valid(self, form):
form.instance.user = self.request.user
form.instance.sequence = SkillGroup.objects.filter(user=self.request.user).order_by('sequence').last().sequence + 1
return super().form_valid(form)
skillgroup_form.html
{% extends "recruiter/baseskills.html" %}
{% load crispy_forms_tags %}
{% block content%}
<div class="content-section">
<form method="post">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Skill Group</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Add Skill Group</button>
</div>
</form>
</div>
{% endblock content%}
我想捕获异常并保存记录(如果不是重复的话),或者在屏幕上显示“技能组已经存在”的消息,并将用户留在创建页面上。另外,如果这是最好的解决方案,我可以删除UniqueConstraint并使用代码进行处理。
答案 0 :(得分:0)
您在这里无意间绕过了Django的表单验证,然后试图将无效输入保存到数据库,这就是Django从数据库反馈丑陋的IntegrityError而不是优雅地处理错误的原因。
如果您在表单中提交了重复的用户和技能组,则void printdata(uint32_t data)
{
Serial.printf("Printing unsigned integer %d", data);
}
// ints should be printed as unsigned ints?
void printdata(int data) {
printdata((uint32_t)data); //Call unsigned version
}
void printdata(float data)
{
Serial.printf("Printing float %i", data);
}
//doubles should be printed as floats
void printdata(double data)
{
printdata((float)data);
}
将有助于将错误消息返回到表单模板中:
但是,只有在表单中包含CreateView
字段时,它才能执行此操作。我假设您已经排除了User来保持表单模板整洁,但这阻止了Django的表单验证检查组合是否已经存在。
要解决此问题,请将User
添加到表单字段中作为隐藏的输入。我认为使用User
的幕后魔术是不可能的,因此您需要创建一个CreateView
来解决这个问题。
SkillGroupForm
# forms.py
from django import forms
from .models import SkillGroup
class SkillGroupForm(forms.ModelForm):
class Meta:
model = SkillGroup
fields = ('user', 'skill_group')
widgets = {
'user': forms.HiddenInput,
}
# views.py
from .forms import SkillGroupForm
class SkillGroupCreateView(LoginRequiredMixin, CreateView):
model = SkillGroup
form_class = SkillGroupForm
def get_initial(self):
return {'user': self.request.user}
def form_valid(self, form):
form.instance.sequence = SkillGroup.objects.filter(user=self.request.user).order_by('sequence').last().sequence + 1
return super().form_valid(form)
方法将get_initial
作为初始值传递到隐藏的表单字段中,因此不需要用户输入。
答案 1 :(得分:0)
尝试验证表单类中的 skill_group 字段。定义 clean_skill_group 方法like in docs。在那里,您可以获得与您的用户相关的所有SkillGroup对象的查询集(例如here),然后比较技能。但是您需要以某种方式将您的User对象或user_id(以获取User对象)推送到表单,然后再调用 form.is_valid()(或再调用一次 form.is_valid( ))。然后在您的html模板中显示表单错误。
class YourForm(forms.ModelForm):
....some fields, Meta....
def clean_skill_group(self):
your_user_object = ....
previously_created_skills = your_user_object.skill_group_set.all()
skill_input = self.cleaned_data["skill_group"]
if skill_input in previously_created_skills:
raise forms.ValidationError(("This skill group is already exist"), code="invalid") # I suppose you are using model form