Django实现表单单次提交及提交报错、字段缺失等相关问题求解
Django开发问题解决方案
问题1:实现用户仅可提交1次表单
要实现该功能需要先关联用户数据,再在视图和模板层做判断:
- 先给
UserBio模型增加用户关联字段,和用户一对一绑定:
from django.contrib.auth.models import User class UserBio(models.Model): # 新增关联字段 user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="bio") # 原有字段保持不变
- 执行迁移命令同步字段到数据库
- 修改视图函数,进入页面前先判断当前登录用户是否已提交过数据:
def add_bio(request): # 新增判断:用户已提交过数据直接返回成功提示 if UserBio.objects.filter(user=request.user).exists(): messages.success(request, '您已提交过表单,无需重复提交') return render(request, 'accounts/profile/add_information.html', {'has_submitted': True}) # 原有逻辑保持不变 if request.method == "POST": # ...后续原有代码
- 模板中增加
has_submitted判断,已提交的用户不用渲染表单即可。
问题2:仅展示1条成功提示
出现两条提示有两个原因,对应调整即可:
- 视图层问题:表单提交成功后没有做重定向,用户刷新页面会触发重复提交,新增第二条提示。修改视图,
form.save()完成后用redirect重定向,不要直接用render返回:
# 顶部导入重定向方法 from django.shortcuts import redirect # 提交成功后修改为 form.save() messages.success(request, '表单提交成功') # 重定向到当前页面,避免刷新重复提交 return redirect('add_bio') # 此处的add_bio替换为你自己的路由名
- 模板层问题:你把alert的div写在了
messages的循环内部,有多少条消息就会生成多少个提示框,同时模板有多余的未闭合标签、冗余标签,修改模板对应部分:
{% if messages %} <div class="alert alert-success" role="alert"> <h4 class="alert-heading">Well done!</h4> {% for message in messages %} <p>{{ message }}</p> {% endfor %} <hr> <p class="mb-0">操作已完成</p> </div> <!-- 删除多余的</ul>标签 --> {% elif not has_submitted %} <form action="" method="POST"> {% csrf_token %} {% bootstrap_form form %} <br/> <input type="submit" value="submit" class="btn btn-primary"> </form> <!-- 补充闭合的form标签 --> {% endif %}
问题3:test_date字段未出现在数据库中
该问题是迁移操作未正确执行导致:
- 你新增
test_date字段后,没有执行python manage.py makemigrations生成迁移文件,或者执行了生成命令但没有运行python manage.py migrate同步修改到数据库。 - 如果执行迁移时报错,检查你之前的迁移文件是否有语法错误,你当前的
test_date = models.DateField(auto_now_add=True)写法是正确的,没有问题。
问题4:自动计算年龄、生成专属ID功能实现
该功能完全可以实现,你之前报错是因为语法和逻辑错误,调整如下:
- 先修复表单的语法错误和字段遗漏:你的表单
fields里漏了birthdate字段,还少了一个单引号,建议修改表单名避免和模型类同名冲突:
class UserBioForm(forms.ModelForm): class Meta: model = UserBio fields = ('name', 'birthdate', 'phone', 'height', 'weight') # 补全单引号和birthdate字段
- 修改视图中的保存逻辑,不要用
self,通过form.save(commit=False)拿到未存入数据库的实例再赋值:
from datetime import date def add_bio(request): # 前面的提交判断逻辑保留 if request.method == "POST": form = UserBioForm(request.POST) if form.is_valid(): # 拿到实例暂不提交到数据库 bio = form.save(commit=False) # 关联当前提交用户 bio.user = request.user # 计算年龄(精确到天,避免生日没到就加一岁的问题) today = date.today() bio.age = str(today.year - bio.birthdate.year - ((today.month, today.day) < (bio.birthdate.month, bio.birthdate.day))) # 生成专属ID bio.id = f"{bio.name}_{bio.height}/{bio.weight}_{bio.phone}" # 正式保存到数据库 bio.save() messages.success(request, '表单提交成功') return redirect('add_bio') # 剩余逻辑保持不变
内容的提问来源于stack exchange,提问作者Kome Gognome
相关产品推荐
相关产品推荐

