一、admin管理数据库
1)models.py创建class类表
class Book(models.Model): name=models.CharField(max_length=20) price=models.IntegerField() pub_date=models.DateField() publish=models.ForeignKey("Publish") authors=models.ManyToManyField("Author") # 会自动生成多对多的book_author的关系表 def __str__(self): return self.name class Publish(models.Model): name=models.CharField(max_length=32) city=models.CharField(max_length=32) def __str__(self): return self.name class Author(models.Model): name=models.CharField(max_length=32) age=models.IntegerField(default=20) def __str__(self): return self.name
models.py
强调:配置文件加入app, LANGUAGE_CODE = ‘zh-hans‘ 修改后台显示语言
python manage.py makemigrations python manage.py migrate python manage.py createsuperuser 生成管理员账号及密码
2)运行Django,输入http://127.0.0.1:8000/admin。
3)添加admin管理model创建的表
name=models.CharField(max_length=20,verbose_name="姓名") 起别名
price=models.IntegerField("价格") # 起别名
from django.contrib import admin from admin_orm import models # Register your models here. admin.site.register(models.Author) admin.site.register(models.Book) admin.site.register(models.Publish)
admin.py
4)自定义admin管理models表
from django.contrib import admin from admin_orm import models # Register your models here. # 自定义表的后台管理 class BookAdmin(admin.ModelAdmin): list_display = (‘id‘,‘name‘,‘price‘,‘pub_date‘) # 字段横着显示,字段显示不能加多对多的字段 list_editable = (‘name‘,‘price‘) # 横着显示,修改字段 filter_horizontal = (‘authors‘,) # 添加字段内容的搜索框 list_per_page = 5 # 分页,显示数据的长度,默认是20条 search_fields = (‘id‘,‘name‘,‘publish__name‘) # 按照字段搜索,publish__name因为关联了别的表,所有以 publish的name搜索 list_filter = (‘pub_date‘,‘publish‘) # 过滤 ordering = ("price",‘id‘) # 排序 # filter_vertical = # 垂直的, # fieldsets =[ # (None, {‘fields‘: [‘title‘]}), # (‘price information‘, {‘fields‘: [‘price‘,"publisher"], ‘classes‘: [‘collapse‘]}), # ] # 隐藏增加属性 admin.site.register(models.Author) admin.site.register(models.Book,BookAdmin) # 引用自定义的后台管理表内容 admin.site.register(models.Publish)
admin.py
二、学生信息管理(自定义网站管理(数据库))
1)创建学生信息表
from django.db import models # Create your models here. class Classes(models.Model): ‘‘‘ 班级表,与老师是 一对多的关系 ‘‘‘ titile = models.CharField(max_length=32) m = models.ManyToManyField("Teachers") class Teachers(models.Model): ‘‘‘ 老师表 ‘‘‘ name = models.CharField(max_length=32) class Student(models.Model): ‘‘‘ 学生表,班级是一对多的关系 ‘‘‘ username = models.CharField(max_length=32) age = models.IntegerField() gender = models.BooleanField() cs = models.ForeignKey(Classes)
models.py
2)编辑前端文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div> <a href="/add_classes.html">添加</a> </div> <div> <table border="1"> <thead> <tr> <th>ID</th> <th>名称</th> <th>操作</th> </tr> </thead> <tbody> {% for row in cls_list %} <tr> <td> {{ row.id }} </td> <td> {{ row.titile}} </td> <td> <a href="/del_classes.html?nid={{ row.id }}">删除</a> | <a href="/edit_classes.html?nid={{ row.id }}">编辑</a> </td> </tr> {% endfor %} </tbody> </table> </div> </body> </html>
get_classes.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="add_classes.html" method="POST"> {% csrf_token %} <input type="text" name="title"> <input type="submit" value="提交"> </form> </body> </html>
add_classes.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="POST" action="/edit_classes.html?nid={{ obj.id }}"> {% csrf_token %} <input type="text" name="xxoo" value="{{ obj.titile }}"/> <input type="submit" value="提交" /> </form> </body> </html>
edit_classes.html
3)定义路由
urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^classes.html‘,classes.get_classes), url(r‘^add_classes.html‘,classes.add_classes), url(r‘^del_classes.html‘, classes.del_classes), url(r‘^edit_classes.html‘, classes.edit_classes), ]
urls.py
4)创建视图函数
from django.shortcuts import render,redirect from app01 import models # Create your views here. def get_classes(request): cls_list = models.Classes.objects.all() return render(request,‘get_classes.html‘,{‘cls_list‘:cls_list}) def add_classes(request): if request.method == "GET": return render(request,‘add_classes.html‘) elif request.method == "POST": title = request.POST.get(‘title‘) models.Classes.objects.create(titile=title) return redirect(‘/classes.html‘) def del_classes(request): nid = request.GET.get(‘nid‘) models.Classes.objects.filter(id = nid).delete() return redirect(‘/classes.html‘) def edit_classes(request): if request.method == ‘GET‘: nid = request.GET.get(‘nid‘) obj = models.Classes.objects.filter(id=nid).first() return render(request,‘edit_classes.html‘,{‘obj‘:obj}) elif request.method == ‘POST‘: nid = request.GET.get(‘nid‘) title = request.POST.get(‘xxoo‘) models.Classes.objects.filter(id=nid).update(titile=title) return redirect(‘/classes.html‘)
views.classes.py
5)展示效果
三、用户登录验证
Django版本的不同,可能需要在settings.py 修改 MIDDLEWARE 为 MIDDLEWARE_CLASS
1)Django的cookie验证
准备html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> * { margin: 0; padding: 0; } </style> </head> <body> <form action="/login/" method="post"> <p>姓名<input type="text" name="user"></p> <p>密码<input type="password" name="pwd"></p> <p><input type="submit"></p> </form> </body> </html>
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> * { margin: 0; padding: 0; } </style> </head> <body> <h1>{{ name }}</h1> </body> </html>
index.html
由于是post的请求
配置文件注释这一行 # ‘django.middleware.csrf.CsrfViewMiddleware‘,
准备url
from django.conf.urls import url from django.contrib import admin from admin_orm import views urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^login/‘, views.login), url(r‘^index/‘, views.index), ]
urls.py
视图函数cookie验证原理
from django.shortcuts import render,redirect # Create your views here. def login(request): print("COOKIES",request.COOKIES) # 查看cookie if request.method == "POST": name = request.POST.get("user") pwd = request.POST.get("pwd") print(name,pwd) if name == "user" and pwd =="123": ret = redirect("/index/") ret.set_cookie("blili",‘acfine‘) # 第一次登陆发送给客户端cookie值 # ret.set_cookie("username",name) return ret return render(request,‘login.html‘) def index(request): if request.COOKIES.get("blili",None) == "acfine": # 第二次登录,携带cookie值 # if request.COOKIES.get("username", None) == "yuan": name = "yuan" return render(request, ‘index.html‘,locals()) else: return redirect("/login/")
views.py
简单优化cookie验证,name = request.COOKIES.get("username",None)
from django.shortcuts import render,redirect # Create your views here. def login(request): print("COOKIES",request.COOKIES) # 查看cookie if request.method == "POST": name = request.POST.get("user") pwd = request.POST.get("pwd") print(name,pwd) if name == "user" and pwd =="123": ret = redirect("/index/") ret.set_cookie("username",{""}) return ret return render(request,‘login.html‘) def index(request): if request.COOKIES.get("username", None): name = request.COOKIES.get("username",None) return render(request, ‘index.html‘,locals()) else: return redirect("/login/")
views.py
2)Django的cookie与session配合实现验证
from django.shortcuts import render,redirect # Create your views here. import datetime expires = datetime.datetime.utcnow()+datetime.timedelta(days=3) def login(request): print("COOKIES",request.COOKIES) # 查看cookie print("SESSION",request.session) if request.method == "POST": name = request.POST.get("user") pwd = request.POST.get("pwd") print(name,pwd) if name == "user" and pwd =="123": # ret = redirect("/index/") # ret.set_cookie("username",{"11":"22"}, # max_age=10, # max_age=10 有效时间10秒,找不到就找后面个 # expires = datetime.datetime.utcnow()+datetime.timedelta(days=3)) # 有效时间3天, # return ret # COOKIE SESSION,session默认在服务端保存15天 request.session["is_login"] = True request.session["user"] = name return redirect("/index/") return render(request,‘login.html‘) def index(request): # if request.COOKIES.get("username", None): # name = request.COOKIES.get("username",None) # return render(request, ‘index.html‘,locals()) if request.session.get("is_login",None): name = request.session.get(‘user‘,None) return render(request,"index.html",locals()) else: return redirect("/login/")
views.py
四、jquery的Ajax应用。不知觉的往后台发请求,而不刷新页面
1)前端文件写入
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .btn{ display: inline-block; padding: 5px 15px; background: darkgoldenrod; color: white; cursor: pointer; } </style> </head> <body> <div> <input placeholder="用户名" type="text" id="username"> <input placeholder="密码" type="password" id="password"> <div class="btn" onclick="submitForm();">提交</div> </div> <div> <input placeholder="数字" type="text" id="i1"> <input placeholder="数字" type="text" id="i2"> <div class="btn" onclick="addForm();">等于</div> <input placeholder="数字" type="text" id="i3"> </div> <script src="/static/jquery-3.2.1.min.js"></script> <script> function submitForm() { var u = $(‘#username‘).val(); var p = $(‘#password‘).val(); console.log(u, p); $.ajax({ url: ‘/ajax2.html‘, type: ‘GET‘, data:{username:u,password:p}, success:function (arg) { console.log(arg); } }) } function addForm(){ var v1 = $(‘#i1‘).val(); var v2 = $(‘#i2‘).val(); $.ajax({ url:‘/ajax3.html‘, type:‘POST‘, data:{"v1":v1,"v2":v2}, success:function(arg){ console.log(arg); $(‘#i3‘).val(arg) //window.location.reload(); //页面刷新 } }) } </script> </body> </html>
ajax1.html
2)路由写入
urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^ajax1.html$‘, ajax.ajax1), url(r‘^ajax2.html$‘, ajax.ajax2), url(r‘^ajax3.html$‘, ajax.ajax3), ]
urls.py
3)视图文件写入
def ajax1(request): return render(request,‘ajax1.html‘) def ajax2(request): user = request.GET.get(‘username‘) pwd = request.GET.get(‘password‘) import time time.sleep(5) return HttpResponse(‘DSB‘) def ajax3(request): v1 = request.POST.get(‘v1‘) v2 = request.POST.get(‘v2‘) try: v3 = int(v1) + int(v2) except Exception as e: v3 = "输入格式有误" return HttpResponse(v3)
view_ajax.py
五、分页功能
1)简单的模拟分页
第一步:分页准备
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for row in user_list %} <li>{{ row.name }}-{{ row.age }}</li> {% endfor %} </ul> </body> </html>
index.html
url(r‘^index.html$‘,views.index)
USER_LIST = [] for i in range(1,999): temp = {‘name‘:‘root‘+str(i),‘age‘:i} USER_LIST.append(temp) def index(request): return render(request,‘index.html‘,{‘user_list‘:USER_LIST})
views.py
第二步:调整url,简单的显示分页功能
USER_LIST = [] for i in range(1,999): temp = {‘name‘:‘root‘+str(i),‘age‘:i} USER_LIST.append(temp) def index(request): per_page_count = 10 current_page = request.GET.get(‘p‘) current_page= int(current_page) start = (current_page-1) * per_page_count end = current_page * per_page_count data = USER_LIST[start:end] return render(request,‘index.html‘,{‘user_list‘:data})
views.py
手动修改url的p值来修改分页显然不现实
2)分页功能实现上一页,下一页展示
修改html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for row in user_list %} <li>{{ row.name }}-{{ row.age }}</li> {% endfor %} </ul> <a href="/index.html?p={{ prev_pager }}">上一页</a> <a href="/index.html?p={{ next_pager }}">下一页</a> </body> </html>
index.html
修改视图函数
USER_LIST = [] for i in range(1,999): temp = {‘name‘:‘root‘+str(i),‘age‘:i} USER_LIST.append(temp) def index(request): per_page_count = 10 current_page = request.GET.get(‘p‘) current_page= int(current_page) start = (current_page-1) * per_page_count end = current_page * per_page_count data = USER_LIST[start:end] prev_pager = current_page -1 next_pager = current_page +1 return render(request,‘index.html‘,{ ‘user_list‘:data, ‘prev_pager‘:prev_pager, ‘next_pager‘:next_pager })
views.py
3)Django的内置分页设计
3.1)增加视图函数
def index1(request): from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger # 全部数据:USER_LIST, ==>得出共有多少条数据 # per_page: 每页显示条目数量 # count: 数据总个数 # num_pages:总页数 # page_range:总页数的索引范围,如:(1,10),(1,200) # page: page对象(是否具有下一页,是否有上一页) current_page = request.GET.get(‘p‘) paginator = Paginator(USER_LIST,10) try: posts = paginator.page(current_page) # has_next 是否有下一页 # next_page_number 下一页页码 # has_previous 是否有上一页 # previous_page_number 上一页页码 # object_list 分页之后的数据列表 # number 当前页 # paginator paginator对象 except PageNotAnInteger: posts = paginator.page(1) except EmptyPage: posts=paginator.page(paginator.num_pages) return render(request, ‘index1.html‘,{‘posts‘:posts})
views.index1
3.2)添加相应的html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for row in posts.object_list %} <li>{{ row.name }}-{{ row.age }}</li> {% endfor %} </ul> {% if posts.has_previous %} <a href="/index1.html?p={{ posts.previous_page_number }}">上一页</a> {% else %} <a href="#">上一页</a> {% endif %} {% if posts.has_next %} <a href="/index1.html?p={{ posts.next_page_number }}">下一页</a> {% endif %} <span> {{ posts.number }} / {{ posts.paginator.num_pages }} </span> </body> </html>
index1.html
3.3)分页功能提取出来,减少代码冗余
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for row in posts.object_list %} <li>{{ row.name }}-{{ row.age }}</li> {% endfor %} </ul> {% include ‘include/pager.html‘ %} </body> </html>
index1.html
添加 include/pager.html 页面
{% if posts.has_previous %} <a href="/index1.html?p={{ posts.previous_page_number }}">上一页</a> {% else %} <a href="#">上一页</a> {% endif %} {% if posts.has_next %} <a href="/index1.html?p={{ posts.next_page_number }}">下一页</a> {% endif %} <span> {{ posts.number }} / {{ posts.paginator.num_pages }} </span>
pager.html
3.4)自定义类,实现自定义分页功能
修改视图
USER_LIST = [] for i in range(1,689): temp = {‘name‘:‘root‘+str(i),‘age‘:i} USER_LIST.append(temp) from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger class CustomPaginator(Paginator): def __init__(self,current_page,per_pager_num,*args,**kwargs): self.current_page = int(current_page) # 当前页 self.per_pager_num = int(per_pager_num) # 最多显示的页面数量 super(CustomPaginator,self).__init__(*args,**kwargs) def pager_num_range(self): if self.num_pages < self.per_pager_num: return range(1,self.num_pages+1) # 总页数特别多 5 part = int(self.per_pager_num/2) if self.current_page <=part: return range(1,self.per_pager_num+1) if (self.current_page +part) > self.num_pages: return range(self.num_pages-self.per_pager_num+1,self.num_pages+1) return range(self.current_page - part, self.current_page + part + 1) def index1(request): # 全部数据:USER_LIST, ==>得出共有多少条数据 # per_page: 每页显示条目数量 # count: 数据总个数 # num_pages:总页数 # page_range:总页数的索引范围,如:(1,10),(1,200) # page: page对象(是否具有下一页,是否有上一页) current_page = request.GET.get(‘p‘) paginator = CustomPaginator(current_page,11,USER_LIST,10) try: posts = paginator.page(current_page) # has_next 是否有下一页 # next_page_number 下一页页码 # has_previous 是否有上一页 # previous_page_number 上一页页码 # object_list 分页之后的数据列表 # number 当前页 # paginator paginator对象 except PageNotAnInteger: posts = paginator.page(1) except EmptyPage: posts=paginator.page(paginator.num_pages) return render(request, ‘index1.html‘,{‘posts‘:posts})
views.py
修改分页前端代码
{% if posts.has_previous %} <a href="/index1.html?p={{ posts.previous_page_number }}">上一页</a> {% else %} <a href="#">上一页</a> {% endif %} {% for i in posts.paginator.pager_num_range %} {% if i == posts.number %} <a style="font-size: 30px;" href="/index1.html?p={{ i }}">{{ i }}</a> {% else %} <a href="/index1.html?p={{ i }}">{{ i }}</a> {% endif %} {% endfor %} {% if posts.has_next %} <a href="/index1.html?p={{ posts.next_page_number }}">下一页</a> {% endif %} <span> {{ posts.number }} / {{ posts.paginator.num_pages }} </span>
pager.html
3.5)模块化定制分页
定制模块,在app01下写入pager.py
#!/usr/bin/env python #-*-coding: utf8-*- class Pagination(object): def __init__(self,totalCount,currentPage,perPageItemNum=10,maxPageNum=7): # 数据总个数 self.total_count = totalCount # 当前页 try: v = int(currentPage) if v <= 0: v = 1 self.current_page = v except Exception as e: self.current_page = 1 # 每页显示的行数 self.per_page_item_num = perPageItemNum # 最多显示页面 self.max_page_num = maxPageNum def start(self): return (self.current_page-1) * self.per_page_item_num def end(self): return self.current_page * self.per_page_item_num @property def num_pages(self): """ 总页数 :return: """ # 666 # 10 a,b = divmod(self.total_count,self.per_page_item_num) if b == 0: return a return a+1 def pager_num_range(self): # self.num_pages() # self.num_pages # 当前页 #self.current_page # 最多显示的页码数量 11 #self.per_pager_num # 总页数 # self.num_pages if self.num_pages < self.max_page_num: return range(1,self.num_pages+1) # 总页数特别多 5 part = int(self.max_page_num/2) if self.current_page <= part: return range(1,self.max_page_num+1) if (self.current_page + part) > self.num_pages: return range(self.num_pages-self.max_page_num+1,self.num_pages+1) return range(self.current_page-part,self.current_page+part+1) def page_str(self): page_list = [] first = "<li><a href=‘/index2.html?p=1‘>首页</a></li>" page_list.append(first) if self.current_page == 1: prev = "<li><a href=‘#‘>上一页</a></li>" else: prev = "<li><a href=‘/index2.html?p=%s‘>上一页</a></li>" %(self.current_page-1,) page_list.append(prev) for i in self.pager_num_range(): if i == self.current_page: temp = "<li class=‘active‘><a href=‘/index2.html?p=%s‘>%s</a></li>" %(i,i) else: temp = "<li><a href=‘/index2.html?p=%s‘>%s</a></li>" % (i, i) page_list.append(temp) if self.current_page == self.num_pages: nex = "<li><a href=‘#‘>下一页</a></li>" else: nex = "<li><a href=‘/index2.html?p=%s‘>下一页</a></li>" % (self.current_page + 1,) page_list.append(nex) last = "<li><a href=‘/index2.html?p=%s‘>尾页</a></li>" %(self.num_pages,) page_list.append(last) return ‘‘.join(page_list)
app01_pager.py
写url路由:url(r‘^index2.html$‘, views.index2),
# 模拟页面内容 USER_LIST = [] for i in range(1,689): temp = {‘name‘:‘root‘+str(i),‘age‘:i} USER_LIST.append(temp) def index2(request): from app01.pager import Pagination current_page = request.GET.get(‘p‘) page_obj = Pagination(666,current_page) data_list = USER_LIST[page_obj.start():page_obj.end()] return render(request,‘index2.html‘,{‘data‘:data_list,‘page_obj‘:page_obj})
views.index2
写入前端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/> </head> <body> <ul> {% for row in data %} <li>{{ row.name }}-{{ row.age }}</li> {% endfor %} </ul> {% for i in page_obj.pager_num_range %} <a href="/index2.html?p={{ i }}">{{ i }}</a> {% endfor %} <hr/>
index2.html
需要导入js的一个插件
展示效果
原文地址:https://www.cnblogs.com/linu/p/9353060.html