首页 > 代码库 > Django框架基础(一)

Django框架基础(一)

Python的WEB框架有Django、Tornado、Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能。

1 安装

技术分享
1 pip3 install django2 # 创建Django程序3  django-admin startproject mysite4 # 进入程序目录5  cd mysite6  # 启动socket服务端,等待用户发送请求7  python manage.py runserver 127.0.0.1:8080
View Code

2 配置

    配置模板路径:

技术分享
1 TEMPLATES=[DIRS: [os.path.join(BASE_DIR, templates)],]
View Code

    配置静态文件路径:

技术分享
1 STATIC_URL = /static/2 STATICFILES_DIRS = (3        os.path.join(BASE_DIR,static),4 )
View Code

   配置数据库:

技术分享
 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     }
View Code
技术分享
由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替    # 如下 放置在与project同名的配置的 __init__.py文件中  import pymysqlpymysql.install_as_MySQLdb()
View Code

   注册app:

技术分享
创建APP(可以创建多个APP,彼此独立)应用于一个项目中可能有多个联系较少的功能        python manage.py starapp app01        app目录简介:             --admin Django自带后台管理相关配置             --modal 写类,根据类创建数据库表             --test  单元测试             --apps  相关配置文件             --views 业务处理
View Code
技术分享
INSTALLED_APPS = [    django.contrib.admin,    django.contrib.auth,    django.contrib.contenttypes,    django.contrib.sessions,    django.contrib.messages,    django.contrib.staticfiles,    app01,]
View Code

    配置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服务
View Code

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
View Code

         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                          pass11                 12                      def post(self,request):13                          pass14             # 2. 在类上添加15                     from django.utils.decorators import method_decorator16                      @method_decorator(wrapper,name=get)17                      class Foo(View):18                 19                         def get(self,request):20                             pass21                 22                         def post(self,request):23                              pass
View Code

 

 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()
View Code

 

                            模板引擎的特殊标记: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 %}
View Code                                                      
技术分享
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>
View Code            

    - 母版:   

技术分享
 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:block55 }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 template13 register=template.Library()14 15 @register.filter()16 def my_upper(value,arg):17     return value + arg18 19 @register.filter()20 def my_bool(value):21     return False
View Code

       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
View Code

 

    - 响应式布局:

                    响应式:
                        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>
View Code

                        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 result11     def get_one(self,sql,arg):12         self.cursor.execute(sql, arg)13         result = self.cursor.fetchone()14         return result15     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.lastrowid22         return last_row_id23     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) 
View Code

生成数据表的命令:

技术分享
1 python manage.py makemigrations #在migrations中记录对数据库的操作2 python manage.py migrate #对数据库进行更新
View Code
技术分享
 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         #in32         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_related53 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‘)]
跨表操作

 

Django框架基础(一)