如何使用Django admin用户表手动添加的字段实现登录校验
落地实现方案
核心逻辑很简单:用户在自定义登录页提交ID和PIN码,后端和Django admin里预存的字段值做匹配,匹配通过就写入授权标记允许访问入住登记页,不通过就打回登录页。
第一步:先核对字段存储位置
你已经手动在admin里录完了ID和PIN的存量数据,先确认这两个字段挂在哪张表上:
- 如果是直接给Django默认
User模型加的字段,后面代码里直接取User对象的对应字段即可 - 如果是建了和
User一对一关联的扩展 profile 表存的,参考下面的模型定义(已经建了就跳过,没建就补完执行迁移)
# models.py from django.db import models from django.contrib.auth.models import User class UserProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) # 下面两个字段名替换成你自己实际建的字段名 custom_id = models.CharField(max_length=64, verbose_name="授权ID") pin_code = models.CharField(max_length=16, verbose_name="PIN码") def __str__(self): return self.user.username
补完模型记得执行
python manage.py makemigrations和python manage.py migrate,再把你之前录的存量数据对应关联到这张表就行。
第二步:补全登录视图逻辑
把你没写完的login视图补完,只做表单取值、库内匹配、授权标记写入三件事:
# views.py from django.shortcuts import render, redirect from django.views.decorators.csrf import csrf_protect from django.contrib import messages # 导入你自己的业务模型,注意你写的chech_in是拼写错误,要是建表时就拼错了就别改,不影响跑 from .models import chech_in, UserProfile def login(request): # 已经过授权的用户直接跳入住页,不用重复登录 if request.session.get("is_authorized"): return redirect("check:checkit") if request.method == "POST": input_id = request.POST.get("custom_id", "").strip() input_pin = request.POST.get("pin_code", "").strip() # 去库里匹配ID+PIN同时符合的记录 try: # 如果字段存在默认User表,把这里的UserProfile换成User,字段名对应替换 matched_user = UserProfile.objects.get(custom_id=input_id, pin_code=input_pin) # 匹配成功写session标记 request.session["is_authorized"] = True request.session["auth_user_id"] = matched_user.user.id return redirect("check:checkit") except UserProfile.DoesNotExist: messages.error(request, "ID或PIN码错误,请重试") return redirect("check:login") # GET请求直接返回登录页 return render(request, "check/login.html")
第三步:给入住登记页加访问校验
你之前写的checkit视图没加权限判断,任何人输对地址都能直接进,要补上授权校验,再加个简单的登出逻辑:
@csrf_protect def checkit(request): # 没授权的直接打回登录页 if not request.session.get("is_authorized"): return redirect("check:login") if request.method == "POST": r_number = request.POST.get("room") a_paid = request.POST.get("amount") o_name = request.POST.get("occuname") o_email = request.POST.get("occumail") o_occupation = request.POST.get("occu") n_of_n = request.POST.get("night") s_date = request.POST.get("start") e_date = request.POST.get("end") new_data = chech_in( room_number=r_number, amount_paid=a_paid, occupant_name=o_name, occupant_email=o_email, occupant_occupation=o_occupation, number_of_nights=n_of_n, start_date=s_date, end_date=e_date ) new_data.save() return redirect('check:checkit') return render(request, 'check/checkin.html') # 登出视图,清掉授权标记 def logout(request): request.session.flush() return redirect("check:login")
第四步:配置路由
在你的app目录下的urls.py里补全三个路由:
# urls.py from django.urls import path from . import views app_name = "check" urlpatterns = [ path("login/", views.login, name="login"), path("logout/", views.logout, name="logout"), path("checkin/", views.checkit, name="checkit"), ]
第五步:写登录页模板
在templates/check/目录下新建login.html,表单只需要ID、PIN两个输入框,记得加csrf令牌:
<!-- check/login.html --> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>入住登记登录</title> </head> <body> <h2>请输入授权信息</h2> {% if messages %} <div style="color: red; margin: 10px 0;"> {% for msg in messages %} <p>{{ msg }}</p> {% endfor %} </div> {% endif %} <form method="POST" action="{% url 'check:login' %}"> {% csrf_token %} <div style="margin: 10px 0;"> <label>授权ID:</label> <input type="text" name="custom_id" required> </div> <div style="margin: 10px 0;"> <label>PIN码:</label> <input type="password" name="pin_code" required> </div> <button type="submit">登录</button> </form> </body> </html>
注意事项
- 代码里的
custom_id、pin_code字段名必须和你自己模型里的实际字段名完全一致,不然会报字段不存在的错误 - 初学阶段先用明文存PIN跑通逻辑即可,后续要上线的话记得给PIN码加哈希加密存储,不要明文存敏感信息
- 默认session在浏览器关闭后就失效,要调整登录有效期的话,在项目
settings.py里加SESSION_COOKIE_AGE = 86400即可,单位是秒,示例值是1天有效期 - 你代码里的
chech_in是拼写错误(正确拼写是check_in),如果之前建表的时候就拼错了就暂时不用改,不影响功能运行,后续迭代再统一修正就行
内容的提问来源于stack exchange,提问作者anthony mensah
相关产品推荐
相关产品推荐

