如何使用Django提取HTML表单提交数据并存入数据库
首先明确:Django 不能通过输入框的ID获取提交的字段值
HTTP 表单提交的规则是,浏览器只会将带name属性的输入项,以name属性值为键、用户输入内容为值组装成请求体发送给服务端。输入框的id仅用于前端DOM操作、和label做绑定,不会被包含在提交的请求数据里,后端根本拿不到id和输入值的映射关系,自然没法通过id取值。
比如你贴的表单里,姓名输入框的name是username、id是name,后端要取这个输入框的值,必须用username作为键查找,和id没有任何关联。
从表单提交到数据存入数据库的完整实现步骤
1. 定义数据库模型
先在对应app的models.py中创建存储用户注册信息的表结构,示例代码如下:
from django.db import models class SiteUser(models.Model): username = models.CharField(max_length=50, verbose_name="用户全名") emailAdress = models.EmailField(verbose_name="邮箱地址") phone = models.CharField(max_length=20, blank=True, null=True, verbose_name="手机号") password = models.CharField(max_length=128, verbose_name="加密密码") create_time = models.DateTimeField(auto_now_add=True, verbose_name="注册时间")
写完模型后在项目根目录执行以下两条命令,将模型同步为数据库中的表:
python manage.py makemigrations:生成数据库迁移文件python manage.py migrate:执行迁移,完成建表
2. 修正前端表单代码
你当前的表单缺少Django要求的CSRF校验令牌,action也没有绑定后端处理地址,需要做简单调整:
<form id="signup-form" action="{% url 'signup' %}" method="post"> {% csrf_token %} <label for="name">Full Name</label> <input autocomplete="off" type="text" name="username" id="name" class="name"> <label for="email">Email Address</label> <input autocomplete="off" type="email" name="emailAdress" id="email" class="email"> <label for="phone">Phone Number - <small>Optional</small></label> <input autocomplete="off" type="text" name="phone" id="phone"> <label for="password">Password</label> <input autocomplete="off" type="password" name="password" id="password" class="pass"> <label for="passwordCon">Confirm Password</label> <input type="password" name="passwordCon" id="passwordCon" class="passConfirm"> <input type="submit" form="signup-form" value="Signup Now" id="submit"> </form>
注意:所有输入项的name属性值要和后续后端取参、模型字段的键保持一致,否则会出现取值失败的问题
3. 编写后端视图处理逻辑
在app的views.py中编写注册逻辑,处理GET请求返回页面、POST请求校验数据并存库:
from django.shortcuts import render, redirect from django.contrib.auth.hashers import make_password from .models import SiteUser def signup(request): # GET请求直接返回注册表单页面 if request.method == "GET": return render(request, "signup.html") # POST请求处理提交的注册数据 if request.method == "POST": # 按input的name属性从POST请求中取值,和id无关 username = request.POST.get("username") email = request.POST.get("emailAdress") phone = request.POST.get("phone", "") password = request.POST.get("password") password_con = request.POST.get("passwordCon") # 基础校验 if not all([username, email, password, password_con]): return render(request, "signup.html", {"error_msg": "必填项不能为空"}) if password != password_con: return render(request, "signup.html", {"error_msg": "两次输入的密码不一致"}) # 数据写入数据库,密码必须加密存储,禁止明文保存 new_user = SiteUser.objects.create( username=username, emailAdress=email, phone=phone, password=make_password(password) ) # 注册成功后跳转到登录页 return redirect("/login/")
4. 配置路由映射
在app的urls.py(没有则新建)中绑定视图和访问地址:
from django.urls import path from . import views urlpatterns = [ path("signup/", views.signup, name="signup"), ]
如果是新建的app级路由文件,需要在项目根目录的urls.py中用include把app路由引入,才能正常访问。
补充说明
- 即使使用Django自带的Form、ModelForm类做表单处理,后端依然是靠输入框的
name属性和表单字段做映射,id始终不参与后端的数据交互。 - 生产环境不建议手写上面的逐字段取值、校验逻辑,推荐直接用
ModelForm,只需要定义好字段映射和校验规则,调用form.save()就能完成数据存库,还能自动处理邮箱格式校验、重复账号拦截、错误信息回显等逻辑,代码更简洁也更安全。 - 绝对不要把用户密码明文存入数据库,必须用Django自带的
make_password做哈希加密,避免数据泄露导致用户账号被盗。
内容的提问来源于stack exchange,提问作者user19069531
相关产品推荐
相关产品推荐

