Django多艺术家选择表单:如何添加重复选择提示?
实现重复选择艺术家的提示功能
一、后端校验与错误反馈优化
你当前在JrtnCurator的save方法里做了重复项判断,但直接在保存阶段抛异常的方式,无法很好地将错误信息传递给前端用户。建议调整为以下更合理的校验逻辑:
1. 模型层添加clean方法做前置校验
把重复校验逻辑移到模型的clean方法中,这样在表单验证阶段(自动调用full_clean)就能触发校验,错误会被表单捕获并返回给用户:
from django.core.exceptions import ValidationError class JrtnCurator(models.Model): expertise = models.ForeignKey(Cexpertise, verbose_name='Экспертиза', on_delete=models.CASCADE) curator = models.ForeignKey(JrtnPerson, verbose_name='Сотрудник Ростехнадзора', on_delete=models.CASCADE) def __str__(self): return '%s' % self.curator class Meta: ordering = ('curator',) verbose_name = 'Куратор от Ростехнадзора' verbose_name_plural = 'Кураторы от Ростехнадзора' # 数据库层面加唯一约束,从根源防止重复数据 unique_together = ('expertise', 'curator') def clean(self): super().clean() # 校验当前订单(expertise)下是否已存在该艺术家,排除自身编辑场景 if JrtnCurator.objects.filter(expertise=self.expertise, curator=self.curator).exclude(pk=self.pk).exists(): raise ValidationError('您重复选择了同一艺术家') def save(self, *args, **kwargs): self.full_clean() super(JrtnCurator, self).save(*args, **kwargs)
2. 表单集层面的批量校验(多选项场景)
如果你的表单是一次性提交多个艺术家选择,需要在表单集类中做整体重复检测:
from django import forms from .models import JrtnCurator class JrtnCuratorFormSet(forms.BaseModelFormSet): def clean(self): super().clean() selected_pairs = [] for form in self.forms: if form.cleaned_data: expertise = form.cleaned_data.get('expertise') curator = form.cleaned_data.get('curator') pair = (expertise.pk, curator.pk) # 检查当前组合是否已存在 if pair in selected_pairs: form.add_error('curator', '您重复选择了同一艺术家') selected_pairs.append(pair)
二、前端实时提示(提升用户体验)
除了后端校验,在前端实时检测用户选择,能让用户立刻发现重复项,避免提交后才收到反馈:
<!-- 假设多选控件为select标签 --> <select id="curator-select" multiple> <!-- 艺术家选项渲染 --> </select> <div id="duplicate-alert" style="color: red; display: none;">您重复选择了同一艺术家</div> <script> const selectEl = document.getElementById('curator-select'); const alertEl = document.getElementById('duplicate-alert'); selectEl.addEventListener('change', () => { const selectedValues = Array.from(selectEl.selectedOptions).map(opt => opt.value); // 通过Set去重后对比长度判断是否有重复 const hasDuplicate = new Set(selectedValues).size !== selectedValues.length; alertEl.style.display = hasDuplicate ? 'block' : 'none'; }); </script>
三、视图与模板的错误渲染
在处理表单提交的视图中,确保捕获验证错误并传递给模板:
from django.shortcuts import render, redirect from .forms import JrtnCuratorFormSet def add_curators(request): if request.method == 'POST': formset = JrtnCuratorFormSet(request.POST) if formset.is_valid(): formset.save() return redirect('success_url') else: formset = JrtnCuratorFormSet() return render(request, 'curator_form.html', {'formset': formset})
模板中渲染表单时,显示对应字段的错误信息:
{% for form in formset %} {{ form.curator.label }}: {{ form.curator }} {% if form.errors.curator %} <span style="color: red;">{{ form.errors.curator.0 }}</span> {% endif %} {% endfor %}
内容的提问来源于stack exchange,提问作者Ksenia Zabelina
相关产品推荐
相关产品推荐

