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

Django中如何将表单选中的单选按钮值保存到数据库

Django答题表单提交写入Answer表落地实现方案

1. 模型字段对齐

先确认你的Answer模型包含所有需要存储的字段,缺省字段直接补全即可,参考定义如下:

# models.py
from django.db import models
from django.contrib.auth import get_user_model

User = get_user_model()

class Question(models.Model):
    # 保留你原有题目模型字段,以下为关联逻辑需要的核心字段示例
    content = models.TextField(verbose_name="题目内容")
    option_a = models.CharField(max_length=200, verbose_name="选项A")
    option_b = models.CharField(max_length=200, verbose_name="选项B")
    option_c = models.CharField(max_length=200, verbose_name="选项C")
    option_d = models.CharField(max_length=200, verbose_name="选项D")
    correct_answer = models.CharField(max_length=2, verbose_name="正确选项")

class Answer(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="答题用户")
    question = models.ForeignKey(Question, on_delete=models.CASCADE, verbose_name="关联题目")
    selected_option = models.CharField(max_length=2, verbose_name="用户选中选项")
    difficulty_rating = models.IntegerField(verbose_name="难度评分")
    confidence_level = models.IntegerField(verbose_name="答题把握度")
    is_correct = models.BooleanField(default=False, verbose_name="是否答对")
    submit_time = models.DateTimeField(auto_now_add=True, verbose_name="提交时间")

    class Meta:
        # 按需开启:限制同一用户对同一题目仅保留一条答题记录,重复提交自动更新
        unique_together = ('user', 'question')

2. 模板表单配置修正

确保表单的请求方法、控件name属性、隐藏参数符合后端接收规则,核心代码如下:

<!-- try.html 答题表单核心片段 -->
<form method="POST" action="{% url 'submit_answer' %}">
    {% csrf_token %}
    <!-- 隐藏域传递当前题目ID,后端靠该参数关联对应题目 -->
    <input type="hidden" name="question_id" value="{{ question.id }}">

    <!-- 单选选项组:所有单选name保持一致,value对应选项标识 -->
    <div class="option-wrap">
        <label><input type="radio" name="selected_option" value="A" required> A. {{ question.option_a }}</label>
        <label><input type="radio" name="selected_option" value="B" required> B. {{ question.option_b }}</label>
        <label><input type="radio" name="selected_option" value="C" required> C. {{ question.option_c }}</label>
        <label><input type="radio" name="selected_option" value="D" required> D. {{ question.option_d }}</label>
    </div>

    <!-- 难度滑块:name与后端字段对应,min/max范围和后端校验规则对齐 -->
    <div class="slider-wrap">
        <label>难度评分:<span id="difficulty-show">3</span>/5</label>
        <input type="range" name="difficulty_rating" min="1" max="5" value="3" required>
    </div>

    <!-- 把握度滑块 -->
    <div class="slider-wrap">
        <label>答题把握度:<span id="confidence-show">3</span>/5</label>
        <input type="range" name="confidence_level" min="1" max="5" value="3" required>
    </div>

    <button type="submit">提交答案</button>
</form>

<!-- 可选:滑块拖动实时显示数值 -->
<script>
document.querySelector('input[name="difficulty_rating"]').addEventListener('input', e => {
    document.querySelector('#difficulty-show').textContent = e.target.value
})
document.querySelector('input[name="confidence_level"]').addEventListener('input', e => {
    document.querySelector('#confidence-show').textContent = e.target.value
})
</script>

3. 路由与视图逻辑实现

3.1 配置提交路由

在应用的urls.py中新增提交接口路由:

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    # 你已有的答题页等路由...
    path('answer/submit/', views.submit_answer, name='submit_answer'),
]

3.2 编写提交入库视图

添加登录校验(未登录用户无法关联账号)、参数合法性校验、入库逻辑,代码如下:

# views.py
from django.shortcuts import get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseBadRequest
from .models import Question, Answer

@login_required(login_url='/your-login-page/') # 替换为你项目的登录页路径
def submit_answer(request):
    # 仅允许POST请求提交
    if request.method != 'POST':
        return HttpResponseBadRequest('非法请求方式')
    
    # 提取表单参数
    question_id = request.POST.get('question_id')
    selected_option = request.POST.get('selected_option')
    difficulty_rating = request.POST.get('difficulty_rating')
    confidence_level = request.POST.get('confidence_level')

    # 基础非空校验
    if not all([question_id, selected_option, difficulty_rating, confidence_level]):
        return HttpResponseBadRequest('提交参数缺失')
    
    # 校验题目是否存在
    question = get_object_or_404(Question, id=question_id)
    # 校验选项值合法
    if selected_option not in ['A', 'B', 'C', 'D']:
        return HttpResponseBadRequest('选项值非法')
    # 校验滑块值为合法范围整数
    try:
        difficulty_rating = int(difficulty_rating)
        confidence_level = int(confidence_level)
        if not (1 <= difficulty_rating <=5 and 1 <= confidence_level <=5):
            raise ValueError
    except ValueError:
        return HttpResponseBadRequest('评分参数非法')

    # 写入数据库:同用户同题目已存在记录则更新,不存在则新建
    answer_record, _ = Answer.objects.update_or_create(
        user=request.user,
        question=question,
        defaults={
            'selected_option': selected_option,
            'difficulty_rating': difficulty_rating,
            'confidence_level': confidence_level,
            'is_correct': selected_option == question.correct_answer
        }
    )

    # 提交成功后跳转,按需修改跳转目标,比如跳转到结果页、下一题页
    return redirect('answer_result', answer_id=answer_record.id)

4. 可选优化

  • 可以用ModelForm封装参数校验逻辑,减少视图层手写校验代码量,适合表单字段多的场景
  • 如果需要无刷新提交,把视图返回逻辑改为返回JsonResponse,前端用ajax提交表单即可
  • 可以接入Django messages框架,在跳转后给用户展示提交成功/答错提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 22:45:43