You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 08:15:04