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
相关产品推荐
相关产品推荐

