Django框架基础(一)

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
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 pymysql
pymysql.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                          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
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- 1190px;
16     background-color: #2b669a;
17     line-height: 48px;
18 }
19 .pg_header .logo{
20     color:white;
21     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       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     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     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=" 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
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-700px){
29             .menus{
30                 display: none;
31             }
32         }
33         @media(min-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) 
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         #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')]
跨表操作

 http://www.cnblogs.com/wuyongqiang/p/7087655.html

原文地址:https://www.cnblogs.com/liuguniang/p/7105740.html