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

Django中如何从下拉选项保存课程名称与Slug两个值?

解决方案

首先明确核心问题:当前模板传递的是课程名称(可能重复),且未利用Django表单的关联验证逻辑,导致无法正确关联课程的slug并保存关联关系。以下是分步修正方案:


1. 确认模型字段类型

确保Welcome模型中的courses字段是多对多关联(因为模板是多选下拉):

# models.py
class Welcome(models.Model):
    message = models.TextField()
    courses = models.ManyToManyField(Course, related_name='welcome_entries')  # 多对多关联Course

2. 修正模板的下拉选项值

将option的value从课程名称改为唯一的slug,确保提交的是可精准匹配的标识:

<select class="form-select" data-search="on" name="courses" multiple>
    <option></option>
    {% for data in courses %}
        <option value="{{ data.slug }}">{{ data.name }}</option>
    {% endfor %}
</select>

3. 调整ModelForm的字段配置

自定义courses字段,指定用slug作为匹配字段,让表单能正确识别提交的slug并关联到Course对象:

# forms.py
class WelcomeForm(ModelForm):
    message = forms.CharField(widget=forms.Textarea)
    # 自定义多对多选择字段,基于slug匹配
    courses = forms.ModelMultipleChoiceField(
        queryset=Course.objects.all(),
        to_field_name='slug',  # 指定用slug作为匹配字段
        widget=forms.SelectMultiple(attrs={'class': 'form-select', 'data-search': 'on'})
    )

    class Meta:
        model = Welcome
        fields = ['message', 'courses']

4. 修正视图逻辑(修复缩进+完善关联保存)

视图存在缩进错误,且多对多关系需要额外调用save_m2m()完成保存:

# views.py
from django.shortcuts import render
from django.contrib import messages
from .models import Welcome, Course
from .forms import WelcomeForm

def add_welcome(request):
    courses = Course.objects.all()  # all()不会抛出ObjectDoesNotExist,无需try-except
    form = WelcomeForm()

    if request.method == 'POST':
        form = WelcomeForm(request.POST)
        if form.is_valid():
            welcome_instance = form.save(commit=False)
            welcome_instance.save()
            form.save_m2m()  # 必须调用此方法保存多对多关联
            messages.success(request, 'Welcome settings has been added successfully')

    context = {'courses': courses, 'form': form}
    return render(request, 'welcome/add_form.html', context)

可选:完全不用Django Forms的手动处理方案

如果坚持不使用ModelForm,可直接手动解析POST数据并关联课程:

# views.py
def add_welcome(request):
    courses = Course.objects.all()

    if request.method == 'POST':
        message = request.POST.get('message')
        selected_slugs = request.POST.getlist('courses')  # 多选需用getlist获取所有值
        # 通过slug筛选对应的课程对象
        selected_courses = Course.objects.filter(slug__in=selected_slugs)
        
        # 创建Welcome实例并关联课程
        welcome = Welcome.objects.create(message=message)
        welcome.courses.add(*selected_courses)
        
        messages.success(request, 'Welcome settings has been added successfully')

    context = {'courses': courses}
    return render(request, 'welcome/add_form.html', context)

模板保持和之前一致即可,这种方式需自行处理数据验证(比如判断slug是否存在),不如ModelForm安全规范。

内容的提问来源于stack exchange,提问作者yoknamitru

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 19:24:21