一、第六天作业
1.查询数据库完成登录功能和注销功能。 注销session可使用del request.session["key名称"],也可通过 request.session.set_expiry(value)设置session过期秒数。
2.使用Ajax完成当用户注册时,判断用户名是否已经存在,如果 在数据库中已经有该用户,则给用户在前台提示“该用户名已存在,请 重新输入注册用户名”。
1.1代码演示
1、models
from django.db import models class RegUser(models.Model): username = models.CharField(max_length=20) password = models.CharField(max_length=20) def __str__(self): return self.username class Meta: db_table = 'regusers' verbose_name = "注册用户模型" verbose_name_plural = verbose_name
2、views
from django.core.paginator import Paginator, Page from django.http import HttpResponse from django.shortcuts import render, redirect from django.urls import reverse from homework.models import RegUser def go_reg(request): return render(request,'register.html') def go_login(request): return render(request,'login.html') def go_success(request): return render(request,'success.html') def wrong_login(request,msg): return render(request, 'login.html',locals()) def login(request): login_name = request.POST["login_name"] login_pwd = request.POST["login_pwd"] if login_name == "tom" and login_pwd == "123456": request.session["loginname"] = login_name # 用户名密码都正确,设置session属性 return redirect(reverse('home:gosuccess')) else: return redirect(reverse('home:wronglogin',args=('用户名或密码错误,请重新登录',))) def logout(request): # 注销 del request.session["loginname"] # 删除session的loginname属性 return redirect(reverse("home:gologin")) def check_regname(request): regname = request.GET["regname"] results = RegUser.objects.filter(username=regname) if results: return HttpResponse("sorry,该用户名已被注册!!!") else: return HttpResponse("恭喜,可以注册~")
3、templates
<!login.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录页面</title> </head> <body> <h3 style="color:red"> {{ msg }}</h3> <form action="{% url 'home:login' %}" method="post"> {% csrf_token %} 用户名:<input type="text" name="login_name"/> <br/> 密码:<input type="password" name="login_pwd"/> <br/> <input type="submit" value="登录"/> </form> </body> </html>
<!success.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>成功页面</title> </head> <body> {% if request.session.loginname %} <h3> 欢迎<span style="color:blue"> {{ request.session.loginname }} 访问本网站 </span> </h3> <a href="{% url 'home:logout' %}">注销</a> {% else %} <h3>您还未登录,请先<a href="{% url 'home:gologin' %}"> 登录 </a></h3> {% endif %} </body> </html>
<!register.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>注册页面</title> <script type="text/javascript"> //AJAX function getXHR(){ var xhr=null; if(window.XMLHttpRequest){ xhr=new XMLHttpRequest() }else{ xhr=new ActiveXObject('Microsoft.XMLHTTP') } return xhr; } function check_regname(){ xhr = getXHR(); // 获取Ajax对象 regname = document.getElementById("regname").value; // 获取输入的注册名 xhr.open('get','/homework/checkname/?regname='+regname,true); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if(xhr.status==200){ var msg=xhr.responseText; // 接收服务端发送的文本 document.getElementById("msg").innerHTML=msg; } } } xhr.send(null); } </script> </head> <body> <form action="" method="post"> {% csrf_token %} 注册用户名:<input type="text" name="reg_name" id="regname" οnblur="check_regname()"/> <span id="msg" style="color:red"></span> <br/> 注册密码:<input type="password" name="reg_pwd"/> <br/> <input type="submit" value="注册"/> </form> </body> </html>
4、urls
#子路由 from django.urls import path from homework.views import * app_name = "homework" urlpatterns = [ path('gologin/',go_login,name="gologin"), path('wronglogin/<msg>/',wrong_login,name='wronglogin'), path('gosuccess/',go_success,name="gosuccess"), path('login/',login,name="login"), path('logout/',logout,name="logout"), path('goreg/',go_reg), path('checkname/',check_regname,name="check"), ] #总路由 path('homework/',include('homework.urls',namespace='home')),
二:Django加载静态资源
Django通过“静态资源探测器”探测的目录,在这些目录下寻找要加载的静态资源。 “静态资源探测器”首先从STATICFILES_DIRS变量(在settings.py中配置)指定的 目录中寻找静态资源;然后去找应用app中的static目录,在该目录中继续寻找静态资源。
1、几个重要配置:
STATIC_URL (必须):指定了访问静态资源的初始URL,当该URL为该变量指定的值时, “静态资源探测器”开始探测静态资源所在的目录。
STATICFILES_DIRS: 指定了“静态资源探测器”的探测目录列表
STATIC_ROOT : 指定了将所有应用的静态资源收集到的目录。 使用python manage.py collectstatic
STATIC_URL = '/abc/' #/abc/可随意修改 STATICFILES_DIRS = [ os.path.join(BASE_DIR,'static'), ] STATIC_ROOT = os.path.join(BASE_DIR,'collectstatic') #然后在终端输入 python manage.py collectstatic
2、模板中如何加载静态资源?
1.加载static标签 {% load static %}2.使用static标签访问静态资源 {% static '静态资源路径' %}
3、代码演示
1、models
from django.db import models class Student(models.Model): name = models.CharField(max_length=20,verbose_name="学生姓名") age = models.IntegerField(verbose_name="学生年龄") sex = models.CharField(max_length=10,verbose_name="性别") score = models.FloatField(verbose_name="成绩") def __str__(self): return self.name class Meta: db_table = 'students' verbose_name_plural = "学生模型"
2、views
from django.core.paginator import Paginator from django.shortcuts import render from myapp.models import Student def go_main(request): return render(request,'main.html') # 根据页码获取对应页码的数据 def get_students_by_page(request,page_number=1): students = Student.objects.all() paginator = Paginator(students,3) # 实例化分页器对象,第一个参数是数据源,第二个参数是每页显示的条数 page = paginator.page(page_number) # 返回page_number页的数据,以Page对象的方式封装该页数据 return render(request,'student/all_students.html',locals())
3、templates
<!DOCTYPE html> {% load static %} <!加载静态资源> <html lang="en"> <head> <meta charset="UTF-8"> <title>主页面</title> </head> <body> <h3>欢迎访问主页面</h3> <img src="{% static 'images/monkey.jpg' %}"/> <!访问静态资源> </body> </html>
<!all_students.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>分页显示所有学生</title> </head> <body> <table border="1" align="center"> <thead> <tr> <th>学号</th> <th>姓名</th> <th>年龄</th> <th>性别</th> <th>成绩</th> </tr> </thead> <tbody> {% for student in page %} <tr> <td> {{ student.id }} </td> <td> {{ student.name }} </td> <td> {{ student.age }} </td> <td> {{ student.sex }} </td> <td> {{ student.score }} </td> </tr> {% endfor %} </tbody> </table> <center> <a href="{% url 'myapp:students' 1 %}">首页</a> {% if page.has_previous %} <a href="{% url 'myapp:students' page.previous_page_number %}">上一页</a> {% else %} <a href="javascript:alert('已经是第一页啦!')">上一页</a> {% endif %} {% if page.has_next %} <a href="{% url 'myapp:students' page.next_page_number %}">下一页</a> {% else %} <a href="javascript:alert('已经是最后一页了!')">下一页</a> {% endif %} <a href="{% url 'myapp:students' paginator.num_pages %}">末页</a> <hr/> {% for page_number in paginator.page_range %} <a href="{% url 'myapp:students' page_number %}"> {{ page_number }} </a> {% endfor %} </center> </body> </html>
4、urls
#子路由 from django.urls import path from myapp.views import * app_name = 'myapp' urlpatterns = [ path('gomain/',go_main), path('students/<page_number>/',get_students_by_page,name="students"), ] #总路由 path('myapp/',include('myapp.urls',namespace='myapp')),
三:admin后台管理
Django提供了一个功能强大的后台管理系统,进入admin系统的路径: http://ip地址:端口号/admin
http://localhost:8000/admin
创建超级用户:python manage.py createsuperuser在应用的admin.py中注册模型: admin.site.register([模型类名称1,模型类名称2...]) 注意:注册模型后,则该模型就可以被admin后台管理了
几个注意点:
-
可以在模型类中复写str(self)方法,后台显示每条记录时会自动调用该方法。
-
改变模型显示的样式:在模型类的class Meta内部类中添加verbose_name_plural。
-
后台中文风格的显示:在settings.py中将LANGUAGE_CODE的值设置为:'zh-Hans'。
#models。py class Meta: db_table = 'regusers' verbose_name = "注册用户模型" verbose_name_plural = verbose_name #去掉复数
#settings.py LANGUAGE_CODE = 'zh-Hans'
四:Django分页器
1.Paginator分页器对象
实例化分页器对象: paginator = Paginator(数据源,每页最多显示的条数)
分页器对象的常用方法: page(页码参数) # 该方法返回一个Page对象,该Page对象封装了某一页的数据
分页器对象的常用属性: num_pages # 返回总的页数 page_range # 返回从1开始的页码范围
2、Page对象(可迭代对象)
常用方法:has_previous() # 当前页是否有前一页previous_page_number() # 前一页的页码has_next() # 当前页是否有下一页next_page_number() # 下一页的页码
3、代码演示
1、models
from django.db import models class Student(models.Model): name = models.CharField(max_length=20,verbose_name="学生姓名")#重命名后台管理名称 age = models.IntegerField(verbose_name="学生年龄") sex = models.CharField(max_length=10,verbose_name="性别") score = models.FloatField(verbose_name="成绩") def __str__(self): return self.name class Meta: db_table = 'students' verbose_name_plural = "学生模型"
2、views
from django.core.paginator import Paginator from django.shortcuts import render from myapp.models import Student def go_main(request): return render(request,'main.html') # 根据页码获取对应页码的数据 def get_students_by_page(request,page_number=1): students = Student.objects.all() paginator = Paginator(students,3) # 实例化分页器对象,第一个参数是数据源,第二个参数是每页显示的条数 page = paginator.page(page_number) # 返回page_number页的数据,以Page对象的方式封装该页数据 return render(request,'student/all_students.html',locals())
3、admin
from django.contrib import admin from myapp.models import Student admin.site.register([Student,])
4、templates
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>分页显示所有学生</title> </head> <body> <table border="1" align="center"> <thead> <tr> <th>学号</th> <th>姓名</th> <th>年龄</th> <th>性别</th> <th>成绩</th> </tr> </thead> <tbody> {% for student in page %} <tr> <td> {{ student.id }} </td> <td> {{ student.name }} </td> <td> {{ student.age }} </td> <td> {{ student.sex }} </td> <td> {{ student.score }} </td> </tr> {% endfor %} </tbody> </table> <center> <a href="{% url 'myapp:students' 1 %}">首页</a> {% if page.has_previous %} <a href="{% url 'myapp:students' page.previous_page_number %}">上一页</a> {% else %} <a href="javascript:alert('已经是第一页啦!')">上一页</a> {% endif %} {% if page.has_next %} <a href="{% url 'myapp:students' page.next_page_number %}">下一页</a> {% else %} <a href="javascript:alert('已经是最后一页了!')">下一页</a> {% endif %} <a href="{% url 'myapp:students' paginator.num_pages %}">末页</a> <hr/> {% for page_number in paginator.page_range %} <a href="{% url 'myapp:students' page_number %}"> {{ page_number }} </a> {% endfor %} </center> </html>
5、urls
#子路由 from django.urls import path from myapp.views import * app_name = 'myapp' urlpatterns = [ path('gomain/',go_main), path('students/<page_number>/',get_students_by_page,name="students"), ] #总路由 path('myapp/',include('myapp.urls',namespace='myapp')),
五:Django内置认证系统
Django内置认证系统的用户类是: from django.contrib.auth.models import User该User模型类对应于auth_user表
1、插入auth_user表中的一条记录
User.objects.create_user(username=regname,password=regpwd) # 使用create_user()创建用户,并对密码加密
2、验证用户名和密码是否正确
user = authenticate(username=login_name,password=login_pwd) # 验证用户名和密码 如果用户名和密码正确,则返回一个User对象;否则返回None
3、登录成功后,将用户与Session关联
login(request,user) # 将用户标识存储到Session中注意:login函数是系统内置的
4、进行登录验证
在模板中使用{% if request.user.is_authenticated %} 登录验证成功后,显示此处{% endif %}
5、注销
logout(request) # 该函数会将后台的Session记录删除
3、代码演示
1、views
from django.contrib.auth import authenticate, login, logout from django.contrib.auth.models import User from django.shortcuts import render, redirect from django.urls import reverse def go_register(request): return render(request,'authapp/register.html') def go_login(request): return render(request, 'authapp/login.html') def wrong_login(request,msg): return render(request, 'authapp/login.html',locals()) def go_success(request): return render(request,'authapp/success.html') # 注册 def register_user(request): regname = request.POST["regname"] regpwd = request.POST["regpwd"] User.objects.create_user(username=regname,password=regpwd) # 使用create_user()创建用户,并对密码加密 return redirect(reverse("authapp:gologin")) # 重定向 # 登录 def user_login(request): login_name = request.POST["login_name"] login_pwd = request.POST["login_pwd"] user = authenticate(username=login_name,password=login_pwd) # 验证用户名和密码 print("查询到的用户是:",user) if user: # 如果验证成功,则返回User对象 print("user的类型是:",type(user)) login(request,user) # 将用户标识存储到Session中 return redirect(reverse("authapp:success")) else: # 如果验证失败,则返回None return redirect(reverse("authapp:wrong",args=("哎呀,输错了,验证失败",))) def user_logout(request): logout(request) # 注销 return redirect(reverse("authapp:gologin")) # 重定向
2、templates
<!register.hteml> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>注册</title> </head> <body> <form action="{% url 'authapp:reg' %}" method="post"> {% csrf_token %} 请输入注册用户名:<input type="text" name="regname"/> <br/> 请输入注册密码:<input type="password" name="regpwd"/> <br/> <input type="submit" value="注册"/> </form> </body> </html>
<!login.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录页面</title> </head> <body> <h3 style="color:red"> {{ msg }} </h3> <form action="{% url 'authapp:login' %}" method="post"> {% csrf_token %} 请输入登录用户名:<input type="text" name="login_name"/> <br/> 请输入登录密码:<input type="password" name="login_pwd"/> <br/> <input type="submit" value="登录"/> </form> </body> </html>
<!success.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>成功页面</title> </head> <body> {% if request.user.is_authenticated %} <h3>Welcome, <span style="color:green"> {{ request.user.username }} ,Nice to meet you~~~</span> </h3> <a href="{% url 'authapp:logout' %}">注销</a> {% else %} <h3>还是先<a href="{% url 'authapp:gologin' %}"> 登录 </a>吧</h3> {% endif %} </body> </html>
3、urls
#子路由 from django.urls import path from authapp.views import * app_name = 'authapp' urlpatterns = [ path('goreg/',go_register), path('gologin/',go_login,name="gologin"), path('wronglogin/<msg>/',wrong_login,name="wrong"), path('gosuccess/',go_success,name="success"), path('register/',register_user,name="reg"), path('login/',user_login,name="login"), path('logout/',user_logout,name="logout"), ] #总路由 path('authapp/',include('authapp.urls',namespace='authapp')),