Python的WEB框架有Django、Tornado、Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能。
1 安装
1 pip3 install django 2 # 创建Django程序 3 django-admin startproject mysite 4 # 进入程序目录 5 cd mysite 6 # 启动socket服务端,等待用户发送请求 7 python manage.py runserver 127.0.0.1:8080
2 配置
配置模板路径:
1 TEMPLATES=[‘DIRS‘: [os.path.join(BASE_DIR, ‘templates‘)],]
配置静态文件路径:
1 STATIC_URL = ‘/static/‘ 2 STATICFILES_DIRS = ( 3 os.path.join(BASE_DIR,‘static‘), 4 )
配置数据库:
1 django默认的数据库是sqlist,我们用的数据库是mysql,所以要更改默认数据库为mysql 2 DATABASES = { 3 ‘default‘: { 4 ‘ENGINE‘: ‘django.db.backends.mysql‘, 5 ‘NAME‘:‘day70‘, 6 ‘USER‘: ‘root‘, 7 ‘PASSWORD‘: ‘123‘, 8 ‘HOST‘: ‘localhost‘, 9 ‘PORT‘: 3306, 10 } 11 }
由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替 # 如下 放置在与project同名的配置的 __init__.py文件中 import pymysql pymysql.install_as_MySQLdb()
注册app:
创建APP(可以创建多个APP,彼此独立)应用于一个项目中可能有多个联系较少的功能 python manage.py starapp app01 app目录简介: --admin Django自带后台管理相关配置 --modal 写类,根据类创建数据库表 --test 单元测试 --apps 相关配置文件 --views 业务处理
INSTALLED_APPS = [ ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘app01‘, ]
配置csrf中间件:
MIDDLEWARE = [ ‘django.middleware.security.SecurityMiddleware‘, ‘django.contrib.sessions.middleware.SessionMiddleware‘, ‘django.middleware.common.CommonMiddleware‘, # ‘django.middleware.csrf.CsrfViewMiddleware‘, ‘django.contrib.auth.middleware.AuthenticationMiddleware‘, ‘django.contrib.messages.middleware.MessageMiddleware‘, ‘django.middleware.clickjacking.XFrameOptionsMiddleware‘, ] #整个项目禁用了CSRF服务
3 路由系统
a /add_user/ def add_user() #静态的 网页url可能为/add_user/?nid=1
b /add_user/(\d+)/ def add_user(request,a1) #动态的 网页url可能为/add_user/1 更加美观,SEO权重更高
c /add_user/(?P<a1>\d+) def add_user(request,a1) #关键词传参和位置传参不可混用
ps: 终止符:^edit$
伪静态:url(r‘^edit/(\w+).html$‘, views.edit), #静态网站访问速度快,可以提高SEO的权重,提高网站访问量
d 路由分发 解决多个app的url设置重名的问题
urls.py
from django.conf.urls import url,include
url(r‘^app01/‘,include(‘app01.urls‘))
app01.urls.py
urlpatterns = [
url(r‘^index.html$‘,views.index),
]
e 给路由关系起名字
url(r‘^login/‘, views.login,name=‘m1‘)
python 代码中可以根据名称反向生成url
1. 后端
from django.urls import reverse
v = reverse(‘n1‘,kwargs={‘a1‘:1111})
print(v)
2.前端 {% url "m1" i %}
SEO是指在了解搜索引擎自然排名机制的基础之上,对网站进行内部及外部的调整优化,改进网站在搜索引擎中关键词的自然排名,获得更多的展现量,吸引更多目标客户点击访问网站,
SEO
4 CBV 与 FBV
FBV:基于函数的视图 function base views
CBV:基于类的视图 class base views
1 urls.py 2 from app01 import views 3 urlpatterns = [ 4 url(r‘^test.html$‘,views.Test.as_view()), 5 6 ] 7 views 8 from django.views import View 9 10 class Login(View): 11 # method : get 查 post 创建 put 更新 delete 删除 12 def get(self,request): 13 pass
CBV中添加装饰器
1 def wrapper(func): 2 def inner(*args,**kwargs): 3 return func(*args,**kwargs) 4 return inner 5 # 1. 指定方法上添加装饰器 6 from django.utils.decorators import method_decorator 7 class Foo(View): 8 @method_decorator(wrapper) 9 def get(self,request): 10 pass 11 12 def post(self,request): 13 pass 14 # 2. 在类上添加 15 from django.utils.decorators import method_decorator 16 @method_decorator(wrapper,name=‘get‘) 17 class Foo(View): 18 19 def get(self,request): 20 pass 21 22 def post(self,request): 23 pass
5 模板
- 基本使用:
模板渲染:将后端数据(数据库中提取的)与前端模板结合(例如jinja2 ) 模板渲染是在后台执行的
1 客户端服务端(前后端)交互是基于http协议通信的,http协议是基于tcp协议之上的,socket是对tcp协议的一个封装, 2 在Django中提供socket服务的是第三方wsgi 3 def index(request): 4 request.POST.getlist 5 request.GET.get 6 request.method 7 8 return render() 9 return HttpResponse() 10 return redirect()
模板引擎的特殊标记:for循环 if判断 索引 函数名-> 自动执行
1 {% for row in user_list_dict %} 2 <tr> 3 <td>{{ row.id }}</td> 4 <td>{{ row.name}}</td> 5 <td>{{ row.email }}</td> 6 </tr> 7 {% endfor %}
1 <p>{{ name }}</p> 2 <p>{{ users.0 }}</p> 3 <p>{{ users.1 }}</p> 4 <p>{{ user_dict.k1 }}</p> 5 <p>{{ user_dict.k2}}</p>
- 母版:
1 body{ 2 margin: 0; 3 } 4 .hide{ 5 display: none; 6 } 7 .left{ 8 float:left; 9 } 10 .right{ 11 float:right; 12 } 13 .pg_header{ 14 height:48px; 15 min-width: 1190px; 16 background-color: #2b669a; 17 line-height: 48px; 18 } 19 .pg_header .logo{ 20 color:white; 21 width:200px; 22 text-align: center; 23 border-right: #1b6d85; 24 font-size: 20px; 25 } 26 .pg_header .rmenus a:hover { 27 background-color:#2aabd2; 28 } 29 .pg_header .rmenus a{ 30 display: inline-block; 31 color:white; 32 padding: 0 20px; 33 34 } 35 .pg_header .avatar img{ 36 width:40px; 37 height:40px; 38 border-radius: 50%; 39 margin: 0 10px; 40 } 41 42 .pg_header .avatar .user-info{ 43 display: none; 44 position: absolute; 45 width:200px; 46 top:48px; 47 right:2px; 48 color:white; 49 background-color: white; 50 border: 1px solid #dddddd; 51 z-index: 1000; 52 } 53 .pg_header .avatar:hover .user-info{ 54 display:block 55 } 56 .pg_header .avatar .user-info a{ 57 display: block; 58 padding: 5px; 59 } 60 .menus{ 61 position:absolute; 62 top:48px; 63 left:0; 64 width:200px; 65 bottom: 0; 66 background-color: #2e6da4; 67 border: solid 1px #1b6d85; 68 } 69 .pg_body .menus a{ 70 display:block; 71 padding: 10px 5px; 72 border-bottom: solid 1px #ffffff; 73 color:white; 74 } 75 76 77 .content{ 78 position: absolute; 79 top:48px; 80 right:0; 81 bottom: 0; 82 left:200px; 83 overflow: scroll; 84 z-index: 999; 85 background-color: #dddddd; 86 }
后台管理母版
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" /> 7 <link rel="stylesheet" href="/static/plugins/font-awesome-4.7.0/css/font-awesome.css" /> 8 <link rel="stylesheet" href="/static/css/commons.css" /> 9 {% block css %}{% endblock %} 10 </head> 11 <body> 12 <div class="pg-header"> 13 <div class="logo left">老男孩后台管理</div> 14 <div class="avatar right" style="position: relative"> 15 <img style="width: 40px;height: 40px;" src="/static/image/1.jpg"> 16 <div class="user-info"> 17 <a>个人资料</a> 18 <a>注销</a> 19 </div> 20 </div> 21 <div class="rmenus right"> 22 <a><i class="fa fa-commenting-o" aria-hidden="true"></i> 消息</a> 23 <a><i class="fa fa-envelope-o" aria-hidden="true"></i> 邮件</a> 24 </div> 25 </div> 26 <div class="pg-body"> 27 <div class="menus"> 28 <a> <i class="fa fa-futbol-o" aria-hidden="true"></i> 班级管理</a> 29 <a>学生管</a> 30 <a>老师管理</a> 31 </div> 32 <div class="content"> 33 <ol class="breadcrumb"> 34 <li><a href="#">首页</a></li> 35 <li><a href="#">班级管理</a></li> 36 <li class="active">添加班级</li> 37 </ol> 38 {% block xx %}{% endblock %} 39 40 </div> 41 </div> 42 {% block js %}{% endblock %} 43 </body> 44 </html>
后台管理母版
1 {% extends ‘layout.html‘ %} 2 3 {% block css %} 4 <style> 5 </style> 6 {% endblock %} 7 8 {% block xx %} 9 10 {% endblock %} 11 12 {% block js %} 13 <script src="/static/jquery-3.2.1.js"></script> 14 <script> 15 </script> 16 {% endblock %}
页面继承
- include
- 导入小组件 {% include ‘public.html‘ %}
- 模板自定义函数:
simple_filter 可以做条件判断 最多两个参数,方式: {{第一个参数|函数名称:"第二个参数"}}
1 html: 2 {{ name|my_upper:‘666‘ }} 3 4 {% if name|my_bool %} 5 True 6 {% else %} 7 False 8 {% endif %} 9 10 11 templatetags文件夹下的py文件: 12 from django import template 13 register=template.Library() 14 15 @register.filter() 16 def my_upper(value,arg): 17 return value + arg 18 19 @register.filter() 20 def my_bool(value): 21 return False
simple_tag 无限制: {% 函数名 参数 参数%}
1 {% my_add name ‘d‘ ‘f‘ ‘g‘ %} 2 3 4 5 from django import template 6 register=template.Library() 7 8 @register.simple_tag() 9 def my_add(value,a1,a2,a3): 10 return value + a1 +a2 +a3
- 响应式布局:
响应式:
1 自己写 @media()
2 bootstrap栅格
1 <html lang="en"> 2 <head> 3 <meta charset="UTF-8"> 4 <title>Title</title> 5 <link rel="stylesheet" href="/static/plugin/bootstrap-3.3.7-dist/css/bootstrap.css"> 6 </head> 7 <body> 8 <div style="background-color: #dddddd"> 9 <div class="col-lg-2" style="background-color: #dddddd">左边</div> 10 <div class="col-lg-10" style="background-color: #0f0f0f">右边</div> 11 </div> 12 <div style="background-color: #dddddd"> 13 <div class="col-md-2" style="background-color: #dddddd">左边</div> 14 <div class="col-md-10" style="background-color: #0f0f0f">右边</div> 15 </div> 16 <div style="background-color: #dddddd"> 17 <div class="col-sm-2" style="background-color: #dddddd">左边</div> 18 <div class="col-sm-10" style="background-color: #0f0f0f">右边</div> 19 </div> 20 <div style="background-color: #dddddd"> 21 <div class="col-xs-2" style="background-color: #dddddd">左边</div> 22 <div class="col-xs-10" style="background-color: #0f0f0f">右边</div> 23 </div> 24 </body> 25 </html>
3 bootstrap导航条
4 bootstrap路径导航
font-awesome 小图标
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 *{ 8 margin: 0; 9 } 10 .left{ 11 float:left; 12 } 13 .right{ 14 float:right; 15 } 16 .header{ 17 position: fixed; 18 width:100%; 19 line-height: 48px; 20 background-color: #5e5e5e; 21 } 22 .header .logo{ 23 color:white; 24 width:200px; 25 text-align: center; 26 font-size: 20px; 27 } 28 @media(max-width:700px){ 29 .menus{ 30 display: none; 31 } 32 } 33 @media(min-width:700px){ 34 .min-menus{ 35 display: none; 36 } 37 } 38 .menus a{ 39 display: inline-block; 40 margin: 0 10px; 41 height:48px; 42 width:48px; 43 color:white; 44 } 45 .menus a:hover{ 46 background-color: #1b6d85; 47 } 48 .header .min-menus{ 49 color:white; 50 } 51 </style> 52 </head> 53 <body> 54 <div class="header"> 55 <div class="logo left">oldboyedu.com</div> 56 <div class="menus left"> 57 <a >主页</a> 58 <a >聊天啊</a> 59 <a >视频</a> 60 <a >邮件</a> 61 </div> 62 <div class="min-menus right">列表</div> 63 64 </div> 65 </body> 66 </html>
自定义响应式
6 ORM
1 class SqlHelper(object): 2 def __init__(self): 3 self.connect() 4 def connect(self): 5 self.conn = pymysql.connect(host=‘localhost‘, port=3306, user=‘root‘, password=‘123‘, db=‘db6‘, charset=‘utf8‘) 6 self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor) 7 def get_list(self,sql,arg): 8 self.cursor.execute(sql, arg) 9 result = self.cursor.fetchall() 10 return result 11 def get_one(self,sql,arg): 12 self.cursor.execute(sql, arg) 13 result = self.cursor.fetchone() 14 return result 15 def modify(self,sql,arg): 16 self.cursor.execute(sql, arg) 17 self.conn.commit() 18 def create(self,sql,arg): 19 self.cursor.execute(sql, arg) 20 self.conn.commit() 21 last_row_id = self.cursor.lastrowid 22 return last_row_id 23 def multiple_modify(self,sql,arg): 24 # self.cursor.executemany(‘insert into bd(id,name)values(%s,%s)‘,[(1,‘alex‘),(2,‘eric‘)]) 25 self.cursor.executemany(sql, arg) 26 self.conn.commit() 27 def close(self): 28 self.cursor.close() 29 self.conn.close()
使用原生sql语句
在Django框架中,对于数据库的操作,支持ORM的方式,一般使用orm操作数据库。其他框架不支持orm,一般使用原生的sql语句
orm操作:可以操作数据表和数据行,但不能创建数据库
创建数据表:
1 class UserGroup(models.Model): 2 title=models.CharField(max_length=64) 3 4 class UserInfo(models.Model): 5 nid=models.BigAutoField(primary_key=True) 6 username=models.CharField(max_length=32) 7 password=models.CharField(max_length=64) 8 age=models.IntegerField(null=True) 9 ug=models.ForeignKey(‘UserGroup‘,null=True)
生成数据表的命令:
1 python manage.py makemigrations #在migrations中记录对数据库的操作 2 python manage.py migrate #对数据库进行更新
1 models.userinfo.object.all() 2 models.userinfo.object.filter(id<2,id>5) 3 models.userinfo.object.all().first() 4 models.userinfo.object.all().count() 5 models.userinfo.object.all().update() 6 models.userinfo.object.all().delete() 7 models.userinfo.object.all().[1:19] 8 9 同时增删改多个数据: 10 1. 增 11 create(name=‘xx‘,age=‘xx‘.....) 12 dic={name"xxx,age} 13 create(**dic) 14 15 2. 更新 16 models.xx.objects.filter(id=1).update(a=1,b=2) 17 18 models.xx.objects.filter(id=1).update(**dic) 19 3. 查询 20 models.xx.objects.filter(id=1,xxx) 21 models.xx.objects.filter(**{‘id‘:1,‘name‘:‘alex‘})
基本操作
1 排序 2 user_list=models.UserInfo.objects.order_by(‘-id‘,‘name‘) 3 for row in user_list: 4 print(row.id) 5 6 分组 7 from django.db.models import Count,Sum,Max,Min 8 v=models.UserInfo.objects.values(‘ut_id‘).annotate(xxxx=Count(‘id‘)) 9 print(v) 10 v1=models.UserInfo.objects.values(‘ut_id‘).annotate(xxxx=Count(‘id‘)).filter(xxxx__gt=2) 11 print(v1) 12 v3=models.UserInfo.objects.filter(id__gt=2).values(‘ut_id‘).annotate(xxxx=Count(‘id‘)).filter(xxxx__gt=1) 13 print(v3) 14 15 过滤 16 models.UserInfo.objects.filter(id__gt=1) 17 models.UserInfo.objects.filter(id__lt=1) 18 models.UserInfo.objects.filter(id__lte=1) 19 models.UserInfo.objects.filter(id__gte=1) 20 models.UserInfo.objects.filter(id__in=[1,2,3]) 21 models.UserInfo.objects.filter(id__range=[1,2]) 22 models.UserInfo.objects.filter(name__startswith=‘xxxx‘) 23 models.UserInfo.objects.filter(name__contains=‘xxxx‘) 24 models.UserInfo.objects.exclude(id=1)
进阶操作
1 # 反转 只有排序之后才可以反转 2 models.UserInfo.objects.all().order_by(‘-id‘).reverse() 3 4 #获取指定条件的数据,以对象的形式返回 5 models.UserInfo.objects.all().only(‘name‘) 6 7 #获取指定条件的数据,以字典的形式返回 8 models.UserInfo.objects.all().values(‘name‘) 9 10 #获取与指定条件相反的数据,以对象的形式返回 11 models.UserInfo.objects.all().defer(‘name‘) 12 13 # 有多个数据库时,设定指定的数据库 14 models.UserInfo.objects.using(‘db2‘) 15 16 # 获取一行数据 17 models.UserInfo.objects.get(id=1) #后面不加限制条件id=1会报错 18 19 # 增加一行数据 20 models.UserType.objects.create(**{‘title‘:‘xxxx‘}) 21 22 obj=models.UserType(title=‘fff‘) 23 obj.save() 24 25 # 批量添加 26 objs=[ 27 models.UserType(title=‘kkkk‘), 28 ] 29 models.UserType.objects.bulk_create(objs,10) 30 31 #in 32 models.UserType.objects.filter(id__in=[1,2,3]) 33 models.UserType.objects.in_bulk([1,2,3]) 34 35 #原生sql 连表操作 36 name_map = {‘title‘: ‘name‘} 37 v1 = models.UserInfo.objects.raw(‘SELECT id,title FROM app01_usertype‘, translations=name_map) 38 39 #获取否则创建 40 obj, created = models.UserInfo.objects.get_or_create( 41 username=‘root1‘, 42 pwd=‘ff‘, 43 defaults={‘email‘: ‘1111111‘,‘u_id‘: 2, ‘t_id‘: 2}) 44 45 # 聚合函数,将整个表作为一组 46 result=models.UserInfo.objects.aggregate(k=Count(‘ut_id‘,distinct=True),n=Count(‘id‘)) 47 print(result) 48 49 #查询值为none的行 50 models.UserInfo.objects.filter(id__isnull=True) 51 52 #提高查询性能的相关命令 select_related prefetch_related 53 54 每次查询都需要连表,整个查询需要11次 55 q=models.UserInfo.objects.all() 56 for row in q: 57 print(row.name,row.ut.title) 58 59 查询主动作连表,整个查询只需一次 60 性能相关:表之间进行join连表操作,一次性获取关联的数据。 61 q=models.UserInfo.objects.all().select_related(‘ut‘) 62 for row in q: 63 print(row.name,row.ut.title) 64 65 不做连表,做多次查询,整个查询只需一次, 66 性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询在Python代码中实现连表操作。 67 q = models.UserInfo.objects.all().prefetch_related(‘ut‘) 68 for row in q: 69 print(row.name, row.ut.title) 70 ### select * from userinfo | django 内部:ut_id=[2,4] | select * from usertype where id in [2,4]
其他操作
1 F,更新时用于获取原来的值 2 from django.db.models import F,Q 3 models.UserInfo.objects.all().update(age=F("age")+1) 4 5 Q,用于构造复杂查询条件 6 # 应用一: 7 # models.UserInfo.objects.filter(Q(id__gt=1)) 8 # models.UserInfo.objects.filter(Q(id=8) | Q(id=2)) 9 # models.UserInfo.objects.filter(Q(id=8) & Q(id=2)) 10 # 应用二: 11 # q1 = Q() 12 # q1.connector = ‘OR‘ 13 # q1.children.append((‘id__gt‘, 1)) 14 # q1.children.append((‘id‘, 10)) 15 # q1.children.append((‘id‘, 9)) 16 # 17 # 18 # q2 = Q() 19 # q2.connector = ‘OR‘ 20 # q2.children.append((‘c1‘, 1)) 21 # q2.children.append((‘c1‘, 10)) 22 # q2.children.append((‘c1‘, 9)) 23 # 24 # q3 = Q() 25 # q3.connector = ‘AND‘ 26 # q3.children.append((‘id‘, 1)) 27 # q3.children.append((‘id‘, 2)) 28 # q2.add(q3,‘OR‘) 29 # 30 # con = Q() 31 # con.add(q1, ‘AND‘) 32 # con.add(q2, ‘AND‘) 33 34 # models.UserInfo.objects.filter(con) 35 extra: 添加其他查询条件 36 37 result=models.UserInfo.objects.filter(id__gt=1).extra( 38 where=[‘app01_userinfo.id < %s‘], 39 params=[100,], 40 tables=[‘app01_usertype‘], 41 order_by=[‘-app01_userinfo.id‘], 42 select={ ‘uid‘:1,‘sw‘:‘select count(1) from app01_usertype where id=%s‘}, 43 select_params=[1] 44 ) 45 46 相当于 47 SELECT (1) AS "uid", (select count(1) from app01_usertype where id=1) AS "sw", "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age", "app01_userinfo"."ut_id" 48 FROM "app01_userinfo" , "app01_usertype" 49 WHERE ("app01_userinfo"."id" > 1 AND (app01_userinfo.id < 100)) 50 ORDER BY ("app01_userinfo".id) DESC
高级操作
1 正向:xxxx.filter(ut__title=‘超级用户‘).values(‘id‘,‘name‘,‘ut__title‘) 2 反向:xxxx.filter(表名称__title=‘超级用户‘).values(‘id‘,‘name‘,‘表名称__title‘) 3 4 UserInfo,ut是FK字段 ---正向操作 5 result=models.UserInfo.objects.all() 6 for obj in result: 7 print(obj.name,obj.age,obj.ut_id,obj.ut.title) 8 9 UserType, 表名小写_set()---反向操作 10 obj=models.UserType.objects.all().first() 11 for row in obj.userinfo_set.all(): 12 print(row.name,row.age) 13 14 跨表 正向操作 15 q=models.UserInfo.objects.all().first() 16 print(q.ut.title) #返回queryset对象 17 q2=models.UserInfo.objects.values(‘id‘,‘ut_id‘,‘ut__title‘) 18 print(q2) # 返回字典 19 q3=models.UserInfo.objects.values_list(‘id‘,‘ut_id‘,‘ut__title‘) 20 print(q3) #返回元组 21 22 跨表 反向操作 23 obj = models.UserType.objects.all().first() 24 p=obj.userinfo_set.all() 25 print(p) #返回queryset对象 [obj,obj,obj,] 26 p1=models.UserType.objects.values(‘id‘,‘title‘,‘userinfo__name‘) 27 print(p1) # 返回字典 [{id:1,name:fd},{id:1,name:fd},{id:1,name:fd},] 28 p2=models.UserType.objects.values_list(‘id‘,‘title‘,‘userinfo__name‘) 29 print(p2) #返回元组 [(1,df),(2,‘df‘)]
跨表操作