[关闭]
@llplmlyd 2019-05-10T03:21:22.000000Z 字数 10126 阅读 1433

Django用户登录注册系统

论文


用户登录注册系统 功能分析

实现以下功能:
用户注册: 注册完成后转到登录页面
用户登录: 登录完成后转到用户资料页面
用户资料页面: 查看用户注册信息,并提供编辑资料按钮
用户资料编辑:编辑完成后转到用户资料查看页面
用户密码重置
用户退出登陆

项目整体文件目录

  1. FSCIIDB
  2. |---FSCIIDB
  3. |--- __init__.py
  4. |--- __pycache__/
  5. |--- settings.py # modified
  6. |--- urls.py # modified
  7. |--- wsgi.py
  8. |---login # created:python manage.py startapp login
  9. |--- __init__.py
  10. |--- admin.py # add to register login: admin.site.register(models.User)
  11. |--- apps.py
  12. |--- forms.py # created file: defaultname is forms.py
  13. |--- urls.py # created file: defaultname is urls.py
  14. |--- models.py # modified
  15. |--- views.py # modified
  16. |--- tests.py
  17. |--- migrations/
  18. |--- static/ # created directory and files as you see
  19. |--- login/
  20. |--- css/
  21. |--- login.css
  22. |--- register.css
  23. |--- img/
  24. |--- templates/ # created directory and files as you see
  25. |--- confirm.html
  26. |--- index.html
  27. |--- login.html
  28. |--- register.html

源代码

1.设计数据表models.py

  1. # models.py
  2. # 可以继承Django自带的User
  3. # coding:utf-8
  4. from django.db import models
  5. from django.contrib.auth.models import AbstractUser
  6. # Create your models here.
  7. # 继承了django中的用户基本 类AbstractUser
  8. class User(AbstractUser):
  9. right_level = [(0, "普通用户"), (1, "司法鉴定员"), (2, "系统用户")]
  10. username = models.CharField("用户名称", unique=True, max_length=50)
  11. # django 要求用户名唯一
  12. password = models.CharField("用户密码", max_length=128)
  13. created_time = models.DateTimeField("账户创建时间", auto_now_add=True)
  14. email = models.EmailField("邮箱")
  15. phone = models.CharField("手机号码", unique=True, max_length=30)
  16. right = models.SmallIntegerField("权限等级", choices=right_level, default=0)
  17. has_confirmed = models.BooleanField(default=False) # 确认
  18. # 元数据 增强可读性
  19. class Meta:
  20. verbose_name = '用户'
  21. ordering = ['-id']
  22. def __str__(self):
  23. return self.username

2 设计登录与注册的表单forms.py

forms.py表单与models.py功能并不相同,forms.py提供快速渲染html表单的方法,并没有与数据库交互,其写入数据库的过程大致可以表示为:
forms.py → templates.html(action/render/redirect) →
views.py (models.User())→ models.py → 数据库

  1. from django import forms
  2. # 用户登录表单
  3. class UserForm(forms.Form):
  4. username = forms.CharField(label="用户名", max_length=50, widget=forms.TextInput(
  5. attrs={'class': 'form-control', 'placeholder': '用户名', 'autofocus': ''}))
  6. password = forms.CharField(label="密码", max_length=30, widget=forms.PasswordInput(
  7. attrs={'class': 'form-control', 'placeholder': '用户密码'}
  8. ))
  9. #用户注册表单
  10. class RegisterForm(forms.Form):
  11. gender = (
  12. ('male', "男"),
  13. ('female', "女"),
  14. )
  15. departments = ((0, "海珠区"), (1, "天河区"), (2, "荔湾区"), (3, "番禺区"),)
  16. username = forms.CharField(label="用户名", max_length=50, widget=forms.TextInput(attrs={'class': 'form-control'}))
  17. password1 = forms.CharField(label="密码", max_length=30, widget=forms.PasswordInput(attrs={'class': 'form-control'}))
  18. password2 = forms.CharField(label="确认密码", max_length=30, widget=forms.PasswordInput(attrs={'class': 'form-control'}))
  19. email = forms.CharField(label="邮箱地址", widget=forms.EmailInput(attrs={'class': 'form-control'}))
  20. # 注意sex这里是Choice
  21. sex = forms.ChoiceField(label="性别", choices=gender)
  22. phone = forms.CharField(label="手机号码", max_length=30, widget=forms.TextInput(attrs={'class': 'form-control'}))
  23. # 注意department这里是Choice
  24. department = forms.ChoiceField(label="所属部门", choices=departments)

3.Templates的HTML设计

这里有几个注意的点:页面逻辑、用户输入提示message、用户验证。
可以说html基本上就是表单的实现,而借用了forms.py 减少了代码的编写量。
confirm.html其实暂时不需要用到

  1. # login.html
  2. {% load static %} # add 引入自己设置的css
  3. <!DOCTYPE html>
  4. <html lang="en">
  5. <head>
  6. <!-- required meta tags --> # 添加注释
  7. <meta charset="UTF-8">、
  8. <!-- Bootstrap CSS --> # add Bootstrap CSS
  9. <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
  10. <link href="{% static 'login/css/login.css' %}" rel="stylesheet" />
  11. <title>FSCI IDC|登录</title> # modified title name
  12. </head>
  13. <body>
  14. <div class="container">
  15. <div class="col">
  16. # 登录表单开始,注意action,将表单发送到哪里
  17. <form class="form-login" action="/login/" method="post">
  18. # 如果有 message 产生 则显示
  19. {% if message %}
  20. <div class="alert alert-warning">{{ message }}</div>
  21. {% endif %}
  22. # django本身的csrf 问题需要在有post的request中添加以下内容
  23. {% csrf_token %}
  24. <h3 class="text-center">法庭科学硅藻鉴定智能数据库</h3>
  25. # form-group 是 Bootstrap CSS的 样式
  26. <div class="form-group">
  27. {{ login_form.username.label_tag }}
  28. {{ login_form.username }}
  29. </div>
  30. <div class="form-group">
  31. {{ login_form.password.label_tag }}
  32. {{ login_form.password }}
  33. </div>
  34. # 这里是登录框的下注内容了
  35. <div>
  36. <a href="/register/" class="text-success"><ins>注册</ins></a>
  37. <button type="submit" class="btn btn-primary float-right">登录</button>
  38. </div>
  39. </form>
  40. </div>
  41. </div><!-- container end -->
  42. <!-- Optional JavaScript -->
  43. <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  44. <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
  45. <script src="https://cdn.bootcss.com/popper.js/1.15.0/umd/popper.min.js"></script>
  46. <script src="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
  47. </body>
  48. </html>
  1. # register.html
  2. # 基本上和login.html实现原理相同
  3. {% load static %}
  4. <!DOCTYPE html>
  5. <html lang="en">
  6. <head>
  7. <!-- required meta tags -->
  8. <meta charset="UTF-8">
  9. <!-- Bootstrap CSS -->
  10. <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
  11. <link href="{% static 'login/css/register.css' %}" rel="stylesheet" />
  12. <title>FSCI IDC|注册</title>
  13. </head>
  14. <body>
  15. <div class="container">
  16. <div class="col">
  17. <form class="form-register" action="/register/" method="post">
  18. {% if message %}
  19. <div class="alert alert-warning">{{ message }}</div>
  20. {% endif %}
  21. {% csrf_token %}
  22. <h3 class="text-center">欢迎注册</h3>
  23. <div class="form-group">
  24. {{ register_form.username.label_tag }}
  25. {{ register_form.username }}
  26. </div>
  27. <div class="form-group">
  28. {{ register_form.password1.label_tag }}
  29. {{ register_form.password1 }}
  30. </div>
  31. <div class="form-group">
  32. {{ register_form.password2.label_tag }}
  33. {{ register_form.password2 }}
  34. </div>
  35. <div class="form-group">
  36. {{ register_form.email.label_tag }}
  37. {{ register_form.email }}
  38. </div>
  39. <div class="form-group">
  40. {{ register_form.sex.label_tag }}
  41. {{ register_form.sex }}
  42. </div>
  43. <div class="form-group">
  44. {{ register_form.department.label_tag }}
  45. {{ register_form.department }}
  46. </div>
  47. <div class="form-group">
  48. {{ register_form.phone.label_tag }}
  49. {{ register_form.phone }}
  50. </div>
  51. <div>
  52. <a href="/login/" class="text-success"><ins>直接登录</ins></a>
  53. <button type="submit" class="btn btn-primary float-right">注册</button>
  54. </div>
  55. </form>
  56. </div>
  57. </div> <!-- container end-->
  58. <!-- Optional JavaScript -->
  59. <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  60. <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
  61. <script src="https://cdn.bootcss.com/popper.js/1.15.0/umd/popper.min.js"></script>
  62. <script src="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
  63. </body>
  64. </html>
  1. # index.html
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>FSCI IDB|首页</title>
  7. </head>
  8. <body>
  9. {% csrf_token %}
  10. <h1>{{ request.session.user_name }}! 欢迎回来! </h1>
  11. {% csrf_token %}
  12. <p>
  13. <a href="/logout/">注销</a>
  14. </p>
  15. </body>
  16. </html>

4 视图函数的设计 views.py

  1. # views.py
  2. from django.shortcuts import render
  3. from django.shortcuts import redirect
  4. from django.conf import settings
  5. from . import models
  6. from . import forms
  7. import hashlib
  8. from django.contrib.auth import authenticate # 用于验证admin账号
  9. import datetime
  10. # Create your views here.
  11. # 普通用户的密码加密方式
  12. def hash_code(s,salt='fsciidb'):
  13. h = hashlib.sha256()
  14. s += salt
  15. h.update(s.encode())
  16. return h.hexdigest()
  17. # 首页视图 使用了模板
  18. def index(request):
  19. # 必须使用session才能进入index页面:
  20. if not request.session.get('is_login', None):
  21. return redirect('/login/')
  22. return render(request, 'index.html')
  23. # 登录视图 使用了模板
  24. def login(request):
  25. if request.session.get('is_login', None):# 不允许重复登录
  26. return redirect('/index/')
  27. if request.method == 'POST':
  28. login_form = forms.UserForm(request.POST)
  29. message = '请检查填写的信息!'
  30. if login_form.is_valid():
  31. username = login_form.cleaned_data.get('username')
  32. password = login_form.cleaned_data.get('password')
  33. temper_user = models.User()
  34. try:
  35. user = models.User.objects.get(username=username)
  36. except:
  37. message = '用户不存在!'
  38. return render(request, 'login.html', locals())
  39. # 管理员登录
  40. user_admin = authenticate(username=username, password=password)
  41. if user_admin:
  42. request.session['is_login'] = True
  43. request.session['user_id'] = user.id
  44. request.session['user_name'] = user.username
  45. return redirect('/index/')
  46. # 普通用户登录
  47. if user.password == hash_code(password):
  48. request.session['is_login'] = True
  49. request.session['user_id'] = user.id
  50. request.session['user_name'] = user.username
  51. return redirect('/index/')
  52. else:
  53. message = '密码不正确!'
  54. return render(request, 'login.html', locals())
  55. else:
  56. return render(request, 'login.html', locals())
  57. login_form = forms.UserForm()
  58. return render(request, 'login.html', locals())
  59. # 注册视图 使用了模板
  60. def register(request):
  61. if request.session.get('is_login', None):
  62. return redirect('/index/')
  63. if request.method == 'POST':
  64. register_form = forms.RegisterForm(request.POST)
  65. message = "请检查填写的信息!"
  66. if register_form.is_valid():
  67. username = register_form.cleaned_data.get('username')
  68. password1 = register_form.cleaned_data.get('password1')
  69. password2 = register_form.cleaned_data.get('password2')
  70. email = register_form.cleaned_data.get('email')
  71. sex = register_form.cleaned_data.get('sex')
  72. department = register_form.cleaned_data.get('department')
  73. phone = register_form.cleaned_data.get('phone')
  74. if password1 != password2:
  75. message = '两次输入密码不同!'
  76. return render(request, 'register.html', locals())
  77. else:
  78. same_phone_user = models.User.objects.filter(phone=phone)
  79. if same_phone_user:
  80. message = '该账号已存在'
  81. return render(request, 'register.html', locals())
  82. same_email_user = models.User.objects.filter(email=email)
  83. if same_email_user:
  84. message = '该邮箱已经被注册'
  85. return render(request, 'register.html', locals())
  86. # 将form表单中输入的内容保存到数据库当中
  87. new_user = models.User()
  88. new_user.username = username
  89. # 数据库不明文存储密码,使用hash加密
  90. new_user.password = hash_code(password1)
  91. new_user.email = email
  92. new_user.sex = sex
  93. new_user.department = department
  94. new_user.phone = phone
  95. # 最后需要使用save()函数保存才能生效
  96. new_user.save()
  97. return render(request, 'confirm.html', locals())
  98. else:
  99. return render(request, 'register.html',locals())
  100. register_form = forms.RegisterForm()
  101. return render(request, 'register.html', locals())
  102. # 注销视图,无使用模板
  103. def logout(request):
  104. if not request.session.get('is_login', None):
  105. return redirect('/login/')
  106. # 清空session 断开连接 回到login界面
  107. request.session.flush()
  108. # del request.session['is_login']
  109. return redirect("/login/")

5.路由设计

  1. # 一级路由urls.py
  2. from django.contrib import admin
  3. from django.urls import path
  4. from django.urls import include
  5. urlpatterns = [
  6. path('admin/', admin.site.urls),
  7. path('',include('login.urls')), # 进入二级路由进行正则匹配判断
  8. ]
  1. # 二级路由urls.py
  2. from django.urls import path
  3. from . import views
  4. urlpatterns = [
  5. path('index/', views.index, name='index'),
  6. path('login/', views.login, name='login'),
  7. path('register/', views.register, name='register'),
  8. path('logout/', views.logout, name='logout'),
  9. ]

6.setting文件设置

  1. DATABASES = {
  2. 'default': {
  3. 'ENGINE': 'django.db.backends.mysql', # your db
  4. # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
  5. 'NAME': 'IDB', # your db_name
  6. 'HOST': '127.0.0.1', # your host
  7. 'USER': 'root', # your db_user
  8. 'PASSWORD': '****', # your db_password
  9. 'PORT': '3306', # your db_port
  10. }
  11. }
  12. LANGUAGE_CODE = 'zh-hans' # modifed by llp
  13. TIME_ZONE = 'Asia/Shanghai' # modifed by llp
  14. USE_TZ = False # modifed by llp
  15. # add by llp 扩展django自身的用户表,需要修改它的模型
  16. # your_aap.models_Name
  17. AUTH_USER_MODEL = 'login.User'
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注