django学习之路

        <p><input type="text" name="name" placeholder="老师姓名" /></p>

        placeholder 默认显示的字符信息



        <select multiple size="10" name="class_ids">
        multiple 多选 size 框大小



    1. 母版
        layout.html
            {% block x1 %}{%endblock%}
            <h1>ff</h1>
            {% block x2 %}{%endblock%}
            <h1>2</h1>...
            {% block x3 %}{%endblock%}
        index.html
            {%extends 'layout'%}
            
            {% block x1 %}dfssssssdfsd{%endblock%}
            
            {% block x2 %}dfsdfsd{%endblock%}
            
            {% block x3 %}fff{%endblock%}
    3. Cookie    
        在浏览器上保存的键值对
        
        def index(request):
            request.COOKIES
            request.get_signed_cookie('k1',salt='ff')
            
            obj = HttpReponse(..)
            obj = render(...)
            obj = redirect(..)
            obj.set_cookie(k1,v1,max_age)
            obj.set_signed_cookie(k1,v1,max_age,salt='fff')
            
    4. BootStrap响应式布局
        - css
        - js(欠)
    
    5. 后台布局
        1. position: absolute
        2. 
            .c1:hover .c2{
            
            }
        
坦白:
    project
        - app01 自己创建的目录,
            - views.py
        - SQLHelper 封装SQL操作
        
    Django:
        - 路由
        - 视图
        - 模板
        - ORM(类-表;对象-行; pymysql连接数据库)
        
    Torando:
        - 路由
        - 视图
        - 模板
        - 自由:pymysql;SqlAchemy
    Flask:
        - 路由
        - 视图
        - 模板(第三方的组件)
        - 自由:pymysql;SqlAchemy
        
        
    1. 创建app
    2. 数据库操作
    

    Django目录介绍
        django-admin startproject mysite
        cd mysite
        python manage.py starapp app01
        
        project
            - app01
                - admin   Django自带后台管理相关配置
                - modal   写类,根据类创建数据库表
                - test    单元测试
                - views   业务处理
            - app02
            - app03

    1. 路由系统
        url -> 函数
        
        a. /login/ -> def login
        
        b. /add-user/(d+)/  ->  def add_user(request,a1)
        
        c. /add-user/(?P<a1>d+)/  ->  def add_user(request,a1)
        
        PS: 
            终止符:
                ^edit$
            伪静态
                url(r'^edit/(w+).html$', views.edit),
        d. 路由分发
            urls.py
                url(r'^app01/', include('app01.urls')),
            
            app01.urls.py
                url(r'^index.html$', views.index),
                
        e. /add-user/(d+)/  ->  def add_user(request,a1)  name=n1
            
            根据名称可以反向生成URL
            1. 在Python代码中
                from django.urls import reverse
                v = reverse('n1',kwargs={'a1':1111})
                print(v)
                
            2. 
                url(r'^login/', views.login,name='m1')
                {% url "m1" %}


cookies 相关
    设置cookie
        set_cookie
        key
        value 
        设置超时时间 推荐使用max_age= 秒      expires=指定的日期 配合datatime使用  

        path 默认是'/' 指定url访问cookie

        domain 域名划分 默认当前域名 一般用不到 sso 统一认证登录 会用到

        安全相关
        secure=False     给https提供的功能
        httponly=False   等于true的时候,只能通过http请求发送,js代码无法获取到


    cookie签名
        set_signed_cookie
            key= ''
            value=''
            salt='加密'    类似MD5中的加盐

        获取
            res = request.get_signedcookie(key,salt='') 

    自定制签名



    装饰器 登录认证    







内容整理
    1 bootstrap 响应式布局  @media()  最大宽度
    2 栅格:
        分成12分 随着宽度改变 样式改变
    3 表格
    
    4 导航条

    5 路径导航    

    6 fontawesome 图标

    7 布局 positione:absolute   fix 固定位置
        内容 overflout

    8  .xx:hover .xx{     }
        当鼠标移动的xx样式的标签上时,其子标签的xx应用以下的属性


    9 django母版 
        共同的东西只写一遍
        母版:
                { % block s1 % }

                { % endblock% }

        子版
            {% extends "layout.html "%}
                { % block s1 % }
                    ...
                    ...
                { % endblock% }


    10 用户登录
        -cookie: 保存在浏览器端的键值对 设置超时时间 path domain 等参数
            发送http请求时,在请求头中携带当前所有访问的cookie
            在响应头中


        - 写cookie
            @xzxx
            def index(request):
            
                obj = HttpResponse('...')
                obj.set_cookie(.....)
                request.COOKIES.get(...)
                
                或者
                
                obj.set_signed_cookie(.....)
                request.get_signed_cookie(....)


        - 自定义cookie签名
        
        - 装饰器装饰views中的函数  检测用户登录

练习
    今日作业:
    1. 布局+代码
    2. 登录+cookie+装饰器
    3. 布局页面HTML+CSS






django 路由

    1 一对一路由   一个url 对应一个函数
            url -> 函数
                
                a. /login/ -> def login
                
                b. /add-user/(d+)/  ->  def add_user(request,a1)
                
                c. /add-user/(?P<a1>d+)/  ->  def add_user(request,a1)

    2 正则表达式路由    

    3 路由分发    针对不同app   
        from django.urls import path,re_path,include
            incloud('xxx') 字符串  

            path('app01/', include('app01.urls')),

            app01 
            re_path('edit/(w+)/', views.edit),

        

        路由中别名name 
            re_path('edit/(w+)/', views.edit,name='n1'),  

            html
                action=“{% url "n1" X %}” 

        反转url 路由 reverce 函数内部处理
            from django.urls import reverse
            url = reverse(viewname,args=('',)或者kwargs={'a1':'xxx',})
            print(reverse("n1",args=(123,)))

    4 终止符    $
        正则匹配路由,以$结尾,
        ^edit$

    5 伪静态  xxx.html$
        路由中必须已index$ 结尾。
            伪静态
        url(r'^edit/(w+).html$', views.edit),





django ORM操作

        Http请求:
            url -> 视图(模板+数据)


        连接数据库操作步骤:
            1. 创建数据库

            2. 修改project中默认连接sqlit为mysql ,setting中设置
                DATABASES = {
                    'default': {
                        'ENGINE': 'django.db.backends.mysql',
                        'NAME':'s4day70db',   数据库名称
                        'USER': 'root',                
                        'PASSWORD': '',
                        'HOST': 'localhost',  
                        'PORT': 3306,
                        }
                }

            3. 在同project同名文件下的init.py 添加 否则会用默认的工具链接mysql
                import pymysql
                pymysql.install_as_MySQLdb()


            4 创建表 app01 models中
            from django.db import models

            # Create your models here.
            class UserInfo(models.Model):
                nid = models.BigAutoField(primary_key=True)  #默认会创建一列id自增主键
                username = models.CharField(max_length=32)   #CharField 必须有max_length
                password = models.CharField(max_length=64)



            5 注册app
                setting中 INSTALLED_APPS 添加app的名字 “  ”


           6 创建数据表 
                   终端执行  **********
                       python manage.py makemigrations
                       python  manage.py migrate

            
            7 创建数据表
                class UserGroup(models.Model):
                    '''
                    部门
                    '''
                    title = models.CharField(max_length=32)
                

                class UserInfo(models.Model):
                    '''
                    员工
                    '''
                    nid = models.BigAutoField(primary_key=True)
                    username = models.CharField(max_length=32)
                    password = models.CharField(max_length=64)
                    age = models.IntegerField(default=1)
                    #创建外键 生成的列名为 ug_id
                    ug = models.ForeignKey('UserGroup',null=True)


            8 单表操作
                class UserGroup(models.Model):
                    """
                    部门
                    """
                    title = models.CharField(max_length=32)
                    ---------------------------------------------------
                    """
                    添加    
                    models.UserGroup.objects.create(title='销售部')

                    删除
                    models.UserGroup.objects.filter(id=2).delete()

                    更新
                    models.UserGroup.objects.filter(id=2).update(title='公关部')

                    查询    
                    group_list = models.UserGroup.objects.all()
                    默认都是Queryset[obj,obj,]

                    只查询第一个 就不是queryset类型,直接是第一个对象
                    group_list = models.UserGroup.objects.all().first() 

                    查询条件
                    group_list = models.UserGroup.objects.filter(id=1)
                    group_list = models.UserGroup.objects.filter(id__gt=1)
                    group_list = models.UserGroup.objects.filter(id__lt=1)


                """

            修改数据库:
                直接修改名称 然后执行两条命令           
               age = models.IntegerField(null=True) 或者default=1,


                #外键 连表操作 跨表去数据 针对对象 基础语法
                    # 获取
                    # QuerySet[obj,obj,obj]
                    # result = models.UserInfo.objects.all()
                    # for obj in result:
                    #     print(obj.name,obj.age,obj.ut_id,obj.ut.title)

                    # UserInfo,ut是FK字段 - 正向操作  PS: 一个用户只有一个用户类型
                    # obj = models.UserInfo.objects.all().first()
                    # print(obj.name,obj.age,obj.ut.title)


                    # UserType, 表名小写_set.all()  - 反向操作   PS: 一个用户类型下可以有很多用户
                    # obj = models.UserType.objects.all().first()
                    # print('用户类型',obj.id,obj.title)
                    # for row in obj.userinfo_set.all():
                    #     print(row.name,row.age)



                     # 数据获取多个数据时  all    values   values_list
                    # 1. [obj,obj,obj,]
                    # models.UserInfo.objects.all()
                    # models.UserInfo.objects.filter(id__gt=1)
                    # result = models.UserInfo.objects.all()
                    # for item in result:
                    #     print(item.name,item.ut.title)

                    # 2. [{id:1,name:fd},{id:1,name:fd},{id:1,name:fd},]
                    # models.UserInfo.objects.all().values('id','name')
                    # models.UserInfo.objects.filter(id__gt=1).values('id','name')
                    # 无法跨表 当前字典内没连表的内容,后续也无法跨表
                    # result = models.UserInfo.objects.all().values('id','name')
                    # for item in result:
                    #     print(item['id'],item['name'])
                    #     
                    # 夸表  双下划线 __ 把连表的值 也取到字典内
                    # result = models.UserInfo.objects.all().values('id','name',"ut__title")
                    # for item in result:
                    #     print(item['id'],item['name'],item['ut__title'])


                    # 3. [(1,df),(2,'df')]
                    # models.UserInfo.objects.all().values_list('id','name')
                    # models.UserInfo.objects.filter(id__gt=1).values_list('id','name')
                    # 无法跨表
                    # result = models.UserInfo.objects.all().values_list('id','name')
                    # for item in result:
                    #     print(item[0],item[1])
                    # 夸表  __
                    # result = models.UserInfo.objects.all().values_list('id','name',"ut__title")
                    # for item in result:
                    #     print(item[0],item[1],item[2])



                # 3. 排序
                    user_list = models.UserInfo.objects.all().order_by('-id','name')
                
                # 4. 分组
                    from django.db.models import Count,Sum,Max,Min
                    # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id'))
                    # print(v.query)
                    # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)
                    # print(v.query)
                    # v =models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)
                    # print(v.query)

                # 5. F,更新时用于获取原来的值
                    from django.db.models import F,Q
                    # models.UserInfo.objects.all().update(age=F("age")+1)



                # 6. Q,用于构造复杂查询条件
                Q使用有两种方式:对象方式,方法方式
                # 应用一:对象方式
                        # models.UserInfo.objects.filter(Q(id__gt=1))
                        # models.UserInfo.objects.filter(Q(id=8) | Q(id=2))
                        # models.UserInfo.objects.filter(Q(id=8) & Q(id=2))
                # 应用二:方法方式
                        # q1 = Q()
                        # q1.connector = 'OR'
                        # q1.children.append(('id__gt', 1))
                        # q1.children.append(('id', 10))
                        # q1.children.append(('id', 9))
                        #
                        #
                        # q2 = Q()
                        # q2.connector = 'OR'
                        # q2.children.append(('c1', 1))
                        # q2.children.append(('c1', 10))
                        # q2.children.append(('c1', 9))
                        #
                        # q3 = Q()
                        # q3.connector = 'AND'
                        # q3.children.append(('id', 1))
                        # q3.children.append(('id', 2))
                        # q2.add(q3,'OR')
                        #
                        # con = Q()
                        # con.add(q1, 'AND')
                        # con.add(q2, 'AND')
                        

                    #例子
                            # 排序
                            # user_list = models.UserInfo.objects.all().order_by('-id','name')
                            # print(user_list)

                            # 分组
                            from django.db.models import Count,Sum,Max,Min
                            # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id'))
                            # print(v.query)
                            # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)
                            # print(v.query)
                            # v =models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)
                            # print(v.query)
                            # 过滤
                            # models.UserInfo.objects.filter(id__gt=1)
                            # models.UserInfo.objects.filter(id__lt=1)
                            # models.UserInfo.objects.filter(id__lte=1)
                            # models.UserInfo.objects.filter(id__gte=1)
                            # models.UserInfo.objects.filter(id__in=[1,2,3])
                            # models.UserInfo.objects.filter(id__range=[1,2])
                            # models.UserInfo.objects.filter(name__startswith='xxxx')
                            # models.UserInfo.objects.filter(name__contains='xxxx')
                            # models.UserInfo.objects.exclude(id=1)

                            # F,Q,extra
                            # from django.db.models import F
                            # models.UserInfo.objects.all().update(age=F("age")+1)

                            # Q
                            # models.UserInfo.objects.filter(id=1,name='root')

                            # condition = {
                            #     'id':1,
                            #     'name': 'root'
                            # }
                            # models.UserInfo.objects.filter(**condition)
                            # Q使用有两种方式:对象方式,方法方式*

                            # from django.db.models import Q
                            # models.UserInfo.objects.filter(Q(id__gt=1))
                            # models.UserInfo.objects.filter(Q(id=8) | Q(id=2))
                            # models.UserInfo.objects.filter(Q(id=8) & Q(id=2))

                             # q1 = Q()
                            # q1.connector = 'OR'
                            # q1.children.append(('id__gt', 1))
                            # q1.children.append(('id', 10))
                            # q1.children.append(('id', 9))
                            #
                            #
                            # q2 = Q()
                            # q2.connector = 'OR'
                            # q2.children.append(('c1', 1))
                            # q2.children.append(('c1', 10))
                            # q2.children.append(('c1', 9))
                            #
                            # q3 = Q()
                            # q3.connector = 'AND'
                            # q3.children.append(('id', 1))
                            # q3.children.append(('id', 2))
                            # q2.add(q3,'OR')
                            #
                            # con = Q()
                            # con.add(q1, 'AND')
                            # con.add(q2, 'AND')

                            # condition_dict = {
                            #     'k1':[1,2,3,4],
                            #     'k2':[1,],
                            # }
                            # con = Q()
                            # for k,v in condition_dict.items():
                            #     q = Q()
                            #     q.connector = 'OR'
                            #     for i in v:
                            #         q.children.append(('id', i))
                            #     con.add(q,'AND')
                            # models.UserInfo.objects.filter(con)
                            #
                            # q1 = Q()
                            # q1.connector = 'OR'
                            # q1.children.append(('id', 1))
                            # q1.children.append(('id', 10))
                            # q1.children.append(('id', 9))
                            #
                            #
                            # q2 = Q()
                            # q2.connector = 'OR'
                            # q2.children.append(('c1', 1))
                            # q2.children.append(('c1', 10))
                            # q2.children.append(('c1', 9))
                            #
                            # q3 = Q()
                            # q3.connector = 'AND'
                            # q3.children.append(('id', 1))
                            # q3.children.append(('id', 2))
                            # q2.add(q3,'OR')
                            #
                            # con = Q()
                            # con.add(q1, 'AND')
                            # con.add(q2, 'AND')
                            # (id=1 or id = 10 or id=9 or (id=1 and id=2)) and (c1=1 or c1=10 or c1=9)



                # 7. extra, 额外查询条件以及相关表,排序
            
                models.UserInfo.objects.filter(id__gt=1)
                models.UserInfo.objects.all() 
                # id name age ut_id
            
            
                models.UserInfo.objects.extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
                # a. 映射
                    # select 
                    # select_params=None
                    # select 此处 from 表
                
                # b. 条件
                    # where=None
                    # params=None,
                    # select * fromwhere 此处
                
                # c. 表
                    # tables
                    # select * from 表,此处
                    
                # c. 排序
                    # order_by=None
                    # select * from 表 order by 此处
                        
                        
                        models.UserInfo.objects.extra(
                            select={'newid':'select count(1) from app01_usertype where id>%s'},
                            select_params=[1,],
                            where = ['age>%s'],
                            params=[18,],
                            order_by=['-age'],
                            tables=['app01_usertype']
                        )
                        """
                        select 
                            app01_userinfo.id,
                            (select count(1) from app01_usertype where id>1) as newid
                        from app01_userinfo,app01_usertype
                        where 
                            app01_userinfo.age > 18
                        order by 
                            app01_userinfo.age desc
                        """
                        
                        result = models.UserInfo.objects.filter(id__gt=1).extra(
                            where=['app01_userinfo.id < %s'],
                            params=[100,],
                            tables=['app01_usertype'],
                            order_by=['-app01_userinfo.id'],
                            select={'uid':1,'sw':"select count(1) from app01_userinfo"}
                        )
                        print(result.query)
                        # SELECT (1) AS "uid", (select count(1) from app01_userinfo) AS "sw", "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age", "app01_userinfo"."ut_id" FROM "app01_userinfo" , "app01_usertype" WHERE ("app01_userinfo"."id" > 1 AND (app01_userinfo.id < 100)) ORDER BY ("app01_userinfo".id) DESC


            # 8. 原生SQL语句
            
                from django.db import connection, connections
                
                cursor = connection.cursor() # connection=default数据
                cursor = connections['db2'].cursor()           #setting中的database名称
                
                cursor.execute("""SELECT * from auth_user where id = %s""", [1])
                
                row = cursor.fetchone()
                row = cursor.fetchall()



                   - 原生SQL语句
                - raw
                    result = models.UserInfo.objects.raw('select * from userinfo')
                    [obj(UserInfo),obj,]
                    result = models.UserInfo.objects.raw('select id,1 as name,2 as age,4 as ut_id from usertype')
                    [obj(UserInfo),obj,]
                    
                    v1 = models.UserInfo.objects.raw('SELECT id,title FROM app01_usertype',translations=name_map)
                    
            # 9. 简单的操作
                http://www.cnblogs.com/wupeiqi/articles/6216618.html


            9 其他  http://www.cnblogs.com/wupeiqi/articles/6216618.html 其他操作
                # v = models.UserInfo.objects.all().only('id','name')
                    # v = models.UserInfo.objects.all().defer('name') 除了name列


                    models.UserInfo.objects.all().using('db2')   用哪个数据库  setting中database的
                    .

                    models.UserInfo.objects.all().filter().all().exclude().only().defer() 可以一直去下去 因为是queryset类型的对象 有。方法,别的不行




                    分组  aggregate  distinct
                    # models.UserInfo.objects.none()
                    # result = models.UserInfo.objects.aggregate(k=Count('ut_id', distinct=True), n=Count('id'))
                    # print(result)

                        #新增 返回的对象 就是新增的数据
                        # obj = models.UserType.objects.create(title='xxx')
                    # obj = models.UserType.objects.create(**{'title': 'xxx'})
                    # print(obj.id)

                    save保存后才会数据库创建
                       # obj = models.UserType(title='xxx')
                        # obj.save()


                    批量增加
                    def bulk_create(self, objs, batch_size=None):
                        # 批量插入
                        # batch_size表示一次插入的个数
                        objs = [
                            models.DDD(name='r11'),
                            models.DDD(name='r22')
                        ]
                        models.DDD.objects.bulk_create(objs, 10)





                    def get_or_create(self, defaults=None, **kwargs):
                    # 如果存在,则获取,否则,创建
                    # defaults 指定创建时,其他字段的值
                    obj, created = models.UserInfo.objects.get_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 2})

                    created 返回的为 True或者是false

                def update_or_create(self, defaults=None, **kwargs):
                    # 如果存在,则更新,否则,创建
                    # defaults 指定创建时或更新时的其他字段
                    obj, created = models.UserInfo.objects.update_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 1})


                    根据主键查询
                        # models.UserInfo.objects.filter(id__in=[1,2,3])
                        # models.UserInfo.objects.in_bulk([1,2,3])


        ==========================补充1==========================select_related   prefetch_related
        # q = models.UserInfo.objects.all()
        # select * from userinfo
        # select * from userinfo inner join usertype on ...
        # for row in q:
        #     print(row.name,row.ut.title)

        # select_related: 查询主动做连表
        # q = models.UserInfo.objects.all().select_related('ut','gp')
        # select * from userinfo
        # select * from userinfo inner join usertype on ...
        # for row in q:
        #     print(row.name,row.ut.title)

        # prefetch_related: 不做连表,做多次查询
        # q = models.UserInfo.objects.all().prefetch_related('ut')
        # select * from userinfo;
        # Django内部:ut_id = [2,4]
        # select * from usertype where id in [2,4]
        # for row in q:
        #     print(row.id,row.ut.title)


# 多对多
    # objs = [
    #     models.Boy(name='方少伟'),
    #     models.Boy(name='由秦兵'),
    #     models.Boy(name='陈涛'),
    #     models.Boy(name='闫龙'),
    #     models.Boy(name='吴彦祖'),
    # ]
    # models.Boy.objects.bulk_create(objs,5)
    #
    # objss = [
    #     models.Girl(nick='小鱼'),
    #     models.Girl(nick='小周'),
    #     models.Girl(nick='小猫'),
    #     models.Girl(nick='小狗'),
    # ]
    # models.Girl.objects.bulk_create(objss,5)

    # models.Love.objects.create(b_id=1,g_id=1)
    # models.Love.objects.create(b_id=1,g_id=4)
    # models.Love.objects.create(b_id=2,g_id=4)
    # models.Love.objects.create(b_id=2,g_id=2)

    # 1. 和方少伟有关系的姑娘
    # obj = models.Boy.objects.filter(name='方少伟').first()
    # love_list = obj.love_set.all()
    # for row in love_list:
    #     print(row.g.nick)
    #
    #
    # love_list = models.Love.objects.filter(b__name='方少伟')
    # for row in love_list:
    #     print(row.g.nick)
    #
    # love_list = models.Love.objects.filter(b__name='方少伟').values('g__nick')
    # for item in love_list:
    #     print(item['g__nick'])
    #
    # love_list = models.Love.objects.filter(b__name='方少伟').select_related('g')
    # for obj in love_list:
    #     print(obj.g.nick)



第三章关系表  可以自己定义类  或者使用内置的生成,但是只能生成三列,两者合用
 
# m = models.ManyToManyField('Boy')     生成第三张关系表


#m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g',)) 告诉django通过love连接,love表的b','g', 来关联 只提供查询和清空的功能


    class Boy(models.Model):
        name = models.CharField(max_length=32)
        m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g',))


    class Girl(models.Model):
        nick = models.CharField(max_length=32)
        # m = models.ManyToManyField('Boy')

    class Love(models.Model):
        b = models.ForeignKey('Boy')
        g = models.ForeignKey('Girl')
#联合唯一索引
        class Meta:
            unique_together = [
                ('b','g'),
            ]

    # obj = models.Boy.objects.filter(name='方少伟').first()
    # print(obj.id,obj.name)
    # obj.m.add(2)
    # obj.m.add(2,4)
    # obj.m.add(*[1,])

    # obj.m.remove(1)
    # obj.m.remove(2,3)
    # obj.m.remove(*[4,])

    # obj.m.set([1,])

    # q = obj.m.all()
    # # [Girl对象]
    # print(q)
    # obj = models.Boy.objects.filter(name='方少伟').first()
    # girl_list = obj.m.all()

    # obj = models.Boy.objects.filter(name='方少伟').first()
    # girl_list = obj.m.all()
    # girl_list = obj.m.filter(nick='小鱼')
    # print(girl_list)

    # obj = models.Boy.objects.filter(name='方少伟').first()
    # obj.m.clear()


    # obj = models.Girl.objects.filter(nick='小鱼').first()
    # print(obj.id,obj.nick)
    # v = obj.boy_set.all()
    # print(v)

        编写ORM  app01 -- models 中
            创建表        
        
        ORM操作表:
            创建表
            修改表
            删除表
        操作数据行:
            增删改查
            
        ORM利用pymysql第三方工具连接数据库
        默认:
            SQLlite
        MySQL:
            mysql -> MySQLDB(修改django默认连接mySQL方式)


XSS 跨站脚本攻击 
    -慎用safe 和mark_safe(导入模块 )
    from django.utils.safestring import mark_safe

    safe 在html中表明

    -非要用,一定要过滤关键字


csrf   一般post提交的时候验证

    FBv使用方法

        a.基本应用 在form中添加 {% csrf_token %}    {{ csrf_token }} 页面会显示随机字符串信息

        b. 全局禁用
            setting中 'django.middleware.csrf.CsrfViewMiddleware', 注释

        c. 局部禁用 
            全局使用,在函数上添加装饰器 
            from django.views.decorators.csrf import csrf_exempt

                @csrf_exempt
                def index():
                    pass
        d.局部使用
            全局禁用 在函数上添加装饰器

            from django.views.decorators.csrf import csrf_protect

                @csrf_protect
                    def index():
                        pass


    CBV使用装饰器方法
        from django.views import View
        from django.utils.decorators import method_decorator

        # 1. CBV应用装饰器
        def wrapper(func):
            def inner(*args,**kwargs):
                return func(*args,**kwargs)
            return inner


        # 1. 指定方法上添加装饰器

            # class Foo(View):
            #
            #     @method_decorator(csrf_protect)
            #     def get(self,request):
            #         pass
            #
            #     def post(self,request):
            #         pass


        # 2. 在类上添加
        #     @method_decorator(csrf_protect,name='dispatch')   #cbv中所有的提交都会先到dispatch 
        #     class Foo(View):
        #
        #         def get(self,request):
        #             pass
        #
        #         def post(self,request):
        #             pass





        Ajax提交数据时候,携带CSRF:
            a. 放置在data中携带
            
                <form method="POST" action="/csrf1.html">
                    {% csrf_token %}
                    <input id="user" type="text" name="user" />
                    <input type="submit" value="提交"/>
                    <a onclick="submitForm();">Ajax提交</a>
                </form>
                <script src="/static/jquery-1.12.4.js"></script>
                <script>
                    function submitForm(){
                        var csrf = $('input[name="csrfmiddlewaretoken"]').val();
                        var user = $('#user').val();
                        $.ajax({
                            url: '/csrf1.html',
                            type: 'POST',
                            data: { "user":user,'csrfmiddlewaretoken': csrf},
                            success:function(arg){
                                console.log(arg);
                            }
                        })
                    }

                </script>
                
            b. 放在请求头中
            
                    <form method="POST" action="/csrf1.html">
                        {% csrf_token %}
                        <input id="user" type="text" name="user" />
                        <input type="submit" value="提交"/>
                        <a onclick="submitForm();">Ajax提交</a>
                    </form>
                    <script src="/static/jquery-1.12.4.js"></script>
                    <script src="/static/jquery.cookie.js"></script>

                    <script>
                        function submitForm(){
                            var token = $.cookie('csrftoken');
                            var user = $('#user').val();
                            $.ajax({
                                url: '/csrf1.html',
                                type: 'POST',
                                headers:{'X-CSRFToken': token},
                                data: { "user":user},
                                success:function(arg){
                                    console.log(arg);
                                }
                            })
                        }
                    </script>



django视图 cbv 、 fbv

    CBV
        先dispatch 判断method 反射
            如果想做定制化的 可以添加在这里

                def dispatch(self, request, *args, **kwargs):
                    print("before")
                    obj=super(Login, self).dispatch(request,*args,**kwargs)
                    print("after")
                    return obj

        url中设置
            re_path('classes/',views.Login.as_view),固定用法

        view设置为
            form表单只有post 和 get 方法,ajex 支持所有
            from django.views import View
            class Login(View):
                '''
                请求方法基本常用的
                    get  查询
                    post 创建
                    put  更新
                    delete 删除
                '''

                def dispatch(self, request, *args, **kwargs):
                    print("before")
                    obj=super(Login, self).dispatch(request,*args,**kwargs)
                    print("after")
                    return obj

                def get(self,request):
                    pass

                def put(self,request):
                    pass
    







django 分页操作
    分批获取数据
        models.UserInfo.objects.all()[0:10]
        models.UserInfo.objects.all()[10:20]




        ---django  自带提供的的分页

        from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage

            def index(request):
                """
                分页
                :param request:
                :return:
                """
                # for i in range(300):
                #     name = "root" + str(i)
                #     models.UserInfo.objects.create(name=name,age=18,ut_id=1)


                current_page = request.GET.get('page')

                user_list = models.UserInfo.objects.all()
                paginator = Paginator(user_list,10)
                # per_page: 每页显示条目数量
                # count:    数据总个数
                # num_pages:总页数
                # page_range:总页数的索引范围,如: (1,10),(1,200)
                # page:     page对象
                try:
                    posts = paginator.page(current_page)
                except PageNotAnInteger as e:
                    posts = paginator.page(1)
                except EmptyPage as e:
                    posts = paginator.page(1)
                # has_next              是否有下一页
                # next_page_number      下一页页码
                # has_previous          是否有上一页
                # previous_page_number  上一页页码
                # object_list           分页之后的数据列表
                # number                当前页
                # paginator             paginator对象
                return render(request,'index.html',{'posts':posts})


    --自定义分页组件

        from utils.pager import PageInfo
        def custom(request):
            # 表示用户当前想要访问的页码: 8

            all_count = models.UserInfo.objects.all().count()

            page_info = PageInfo(request.GET.get('page'),all_count,10,'/custom.html',11)
            user_list = models.UserInfo.objects.all()[page_info.start():page_info.end()]

            return render(request,'custom.html',{'user_list':user_list,'page_info':page_info})


            class PageInfo(object):

                def __init__(self,current_page,all_count,per_page,base_url,show_page=11):
                    """

                    :param current_page:
                    :param all_count: 数据库总行数
                    :param per_page: 每页显示函数
                    :return:
                    """
                    try:
                        self.current_page = int(current_page)
                    except Exception as e:
                        self.current_page = 1
                    self.per_page = per_page

                    a,b = divmod(all_count,per_page)
                    if b:
                        a = a +1
                    self.all_pager = a
                    self.show_page = show_page
                    self.base_url = base_url
                def start(self):
                    return (self.current_page-1) * self.per_page

                def end(self):
                    return self.current_page * self.per_page


                def pager(self):
                    # v = "<a href='/custom.html?page=1'>1</a><a href='/custom.html?page=2'>2</a>"
                    # return v
                    page_list = []

                    half = int((self.show_page-1)/2)

                    # 如果数据总页数 < 11
                    if self.all_pager < self.show_page:
                        begin = 1
                        stop = self.all_pager + 1
                    # 如果数据总页数 > 11
                    else:
                        # 如果当前页 <=5,永远显示1,11
                        if self.current_page <= half:
                            begin = 1
                            stop = self.show_page + 1
                        else:
                            if self.current_page + half > self.all_pager:
                                begin = self.all_pager - self.show_page + 1
                                stop = self.all_pager + 1
                            else:
                                begin = self.current_page - half
                                stop = self.current_page + half + 1

                    if self.current_page <= 1:
                        prev = "<li><a href='#'>上一页</a></li>"
                    else:
                        prev = "<li><a href='%s?page=%s'>上一页</a></li>" %(self.base_url,self.current_page-1,)
                    page_list.append(prev)

                    for i in range(begin,stop):
                        if i == self.current_page:
                            temp = "<li class='active'><a  href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,)
                        else:
                            temp = "<li><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,)
                        page_list.append(temp)

                    if self.current_page >= self.all_pager:
                        nex = "<li><a href='#'>下一页</a></li>"
                    else:
                        nex = "<li><a href='%s?page=%s'>下一页</a></li>" %(self.base_url,self.current_page+1,)
                    page_list.append(nex)


                    return ''.join(page_list)


                <!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <title></title>
                    <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" />
                </head>
                <body>
                    <h1>用户列表</h1>
                    <ul>
                        {% for row in user_list %}
                            <li>{{ row.name }}</li>
                        {% endfor %}
                    </ul>

                    <nav aria-label="Page navigation">
                      <ul class="pagination">
                          {{ page_info.pager|safe }}
                      </ul>
                    </nav>
                </body>
                </html>




        <p><input type="text" name="name" placeholder="老师姓名" /></p>
        placeholder 默认显示的字符信息


        <select multiple size="10" name="class_ids">        multiple 多选 size 框大小


1. 母版layout.html{% block x1 %}{%endblock%}<h1>ff</h1>{% block x2 %}{%endblock%}<h1>2</h1>...{% block x3 %}{%endblock%}index.html{%extends 'layout'%}{% block x1 %}dfssssssdfsd{%endblock%}{% block x2 %}dfsdfsd{%endblock%}{% block x3 %}fff{%endblock%}3. Cookie在浏览器上保存的键值对def index(request):request.COOKIESrequest.get_signed_cookie('k1',salt='ff')obj = HttpReponse(..)obj = render(...)obj = redirect(..)obj.set_cookie(k1,v1,max_age)obj.set_signed_cookie(k1,v1,max_age,salt='fff')4. BootStrap响应式布局- css- js(欠)5. 后台布局1. position: absolute2. .c1:hover .c2{}坦白:project- app01 自己创建的目录,- views.py- SQLHelper 封装SQL操作Django:- 路由- 视图- 模板- ORM(类-表;对象-行; pymysql连接数据库)Torando:- 路由- 视图- 模板- 自由:pymysql;SqlAchemyFlask:- 路由- 视图- 模板(第三方的组件)- 自由:pymysql;SqlAchemy1. 创建app2. 数据库操作
Django目录介绍django-admin startproject mysitecd mysitepython manage.py starapp app01project- app01- admin   Django自带后台管理相关配置- modal   写类,根据类创建数据库表- test    单元测试- views   业务处理- app02- app03
1. 路由系统url -> 函数a. /login/ -> def loginb. /add-user/(d+)/  ->  def add_user(request,a1)c. /add-user/(?P<a1>d+)/  ->  def add_user(request,a1)PS: 终止符:^edit$伪静态url(r'^edit/(w+).html$', views.edit),d. 路由分发urls.pyurl(r'^app01/', include('app01.urls')),app01.urls.pyurl(r'^index.html$', views.index),e. /add-user/(d+)/  ->  def add_user(request,a1)  name=n1根据名称可以反向生成URL1. 在Python代码中from django.urls import reversev = reverse('n1',kwargs={'a1':1111})print(v)2. url(r'^login/', views.login,name='m1'){% url "m1" %}

cookies 相关设置cookieset_cookiekeyvalue 设置超时时间 推荐使用max_age= 秒      expires=指定的日期 配合datatime使用  
path 默认是'/' 指定url访问cookie
domain 域名划分 默认当前域名 一般用不到 sso 统一认证登录 会用到
安全相关secure=False     给https提供的功能httponly=False   等于true的时候,只能通过http请求发送,js代码无法获取到

cookie签名set_signed_cookiekey= ''value=''salt='加密'类似MD5中的加盐
获取res = request.get_signedcookie(key,salt='') 
自定制签名


装饰器 登录认证






内容整理1 bootstrap 响应式布局  @media()  最大宽度2 栅格:分成12分 随着宽度改变 样式改变3 表格4 导航条
5 路径导航
6 fontawesome 图标
7 布局 positione:absolute   fix 固定位置内容 overflout
8  .xx:hover .xx{     }当鼠标移动的xx样式的标签上时,其子标签的xx应用以下的属性

9 django母版 共同的东西只写一遍母版:{ % block s1 % }
{ % endblock% }
子版{% extends "layout.html "%}{ % block s1 % }......{ % endblock% }

    10 用户登录    -cookie: 保存在浏览器端的键值对 设置超时时间 path domain 等参数    发送http请求时,在请求头中携带当前所有访问的cookie    在响应头中

- 写cookie@xzxxdef index(request):obj = HttpResponse('...')obj.set_cookie(.....)request.COOKIES.get(...)或者obj.set_signed_cookie(.....)request.get_signed_cookie(....)

- 自定义cookie签名- 装饰器装饰views中的函数  检测用户登录
练习今日作业:1. 布局+代码2. 登录+cookie+装饰器3. 布局页面HTML+CSS





django 路由
1 一对一路由   一个url 对应一个函数url -> 函数a. /login/ -> def loginb. /add-user/(d+)/  ->  def add_user(request,a1)c. /add-user/(?P<a1>d+)/  ->  def add_user(request,a1)
2 正则表达式路由    
3 路由分发    针对不同app   from django.urls import path,re_path,includeincloud('xxx') 字符串  
path('app01/', include('app01.urls')),
app01 re_path('edit/(w+)/', views.edit),

路由中别名name re_path('edit/(w+)/', views.edit,name='n1'),  
htmlaction=“{% url "n1" X %}” 
反转url 路由 reverce 函数内部处理from django.urls import reverseurl = reverse(viewname,args=('',)或者kwargs={'a1':'xxx',})print(reverse("n1",args=(123,)))
4 终止符    $正则匹配路由,以$结尾,^edit$
5 伪静态  xxx.html$路由中必须已index$ 结尾。伪静态url(r'^edit/(w+).html$', views.edit),




django ORM操作
Http请求:url -> 视图(模板+数据)

连接数据库操作步骤:1. 创建数据库
2. 修改project中默认连接sqlit为mysql ,setting中设置DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME':'s4day70db',   数据库名称'USER': 'root','PASSWORD': '','HOST': 'localhost',  'PORT': 3306,}}
3. 在同project同名文件下的init.py 添加 否则会用默认的工具链接mysqlimport pymysqlpymysql.install_as_MySQLdb()

4 创建表 app01 models中from django.db import models
# Create your models here.class UserInfo(models.Model):    nid = models.BigAutoField(primary_key=True)  #默认会创建一列id自增主键    username = models.CharField(max_length=32)   #CharField 必须有max_length    password = models.CharField(max_length=64)


   5 注册app    setting中 INSTALLED_APPS 添加app的名字 “  ”

  6 创建数据表    终端执行  **********   python manage.py makemigrations   python  manage.py migrate
7 创建数据表class UserGroup(models.Model):    '''    部门    '''    title = models.CharField(max_length=32)
class UserInfo(models.Model):    '''    员工    '''    nid = models.BigAutoField(primary_key=True)    username = models.CharField(max_length=32)    password = models.CharField(max_length=64)    age = models.IntegerField(default=1)    #创建外键 生成的列名为 ug_id    ug = models.ForeignKey('UserGroup',null=True)

8 单表操作class UserGroup(models.Model):    """    部门    """    title = models.CharField(max_length=32)    ---------------------------------------------------"""添加models.UserGroup.objects.create(title='销售部')
删除models.UserGroup.objects.filter(id=2).delete()
更新models.UserGroup.objects.filter(id=2).update(title='公关部')
查询group_list = models.UserGroup.objects.all()默认都是Queryset[obj,obj,]
只查询第一个 就不是queryset类型,直接是第一个对象group_list = models.UserGroup.objects.all().first() 
查询条件group_list = models.UserGroup.objects.filter(id=1)group_list = models.UserGroup.objects.filter(id__gt=1)group_list = models.UserGroup.objects.filter(id__lt=1)

"""
修改数据库:直接修改名称 然后执行两条命令     age = models.IntegerField(null=True) 或者default=1,

#外键 连表操作 跨表去数据 针对对象 基础语法    # 获取    # QuerySet[obj,obj,obj]    # result = models.UserInfo.objects.all()    # for obj in result:    #     print(obj.name,obj.age,obj.ut_id,obj.ut.title)
   # UserInfo,ut是FK字段 - 正向操作  PS: 一个用户只有一个用户类型    # obj = models.UserInfo.objects.all().first()    # print(obj.name,obj.age,obj.ut.title)

   # UserType, 表名小写_set.all()  - 反向操作   PS: 一个用户类型下可以有很多用户    # obj = models.UserType.objects.all().first()    # print('用户类型',obj.id,obj.title)    # for row in obj.userinfo_set.all():    #     print(row.name,row.age)


    # 数据获取多个数据时  all    values   values_list    # 1. [obj,obj,obj,]    # models.UserInfo.objects.all()    # models.UserInfo.objects.filter(id__gt=1)    # result = models.UserInfo.objects.all()    # for item in result:    #     print(item.name,item.ut.title)
   # 2. [{id:1,name:fd},{id:1,name:fd},{id:1,name:fd},]    # models.UserInfo.objects.all().values('id','name')    # models.UserInfo.objects.filter(id__gt=1).values('id','name')    # 无法跨表 当前字典内没连表的内容,后续也无法跨表    # result = models.UserInfo.objects.all().values('id','name')    # for item in result:    #     print(item['id'],item['name'])    #         # 夸表  双下划线 __ 把连表的值 也取到字典内    # result = models.UserInfo.objects.all().values('id','name',"ut__title")    # for item in result:    #     print(item['id'],item['name'],item['ut__title'])

   # 3. [(1,df),(2,'df')]    # models.UserInfo.objects.all().values_list('id','name')    # models.UserInfo.objects.filter(id__gt=1).values_list('id','name')    # 无法跨表    # result = models.UserInfo.objects.all().values_list('id','name')    # for item in result:    #     print(item[0],item[1])    # 夸表  __    # result = models.UserInfo.objects.all().values_list('id','name',"ut__title")    # for item in result:    #     print(item[0],item[1],item[2])


    # 3. 排序user_list = models.UserInfo.objects.all().order_by('-id','name')# 4. 分组from django.db.models import Count,Sum,Max,Min# v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id'))# print(v.query)# v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)# print(v.query)# v =models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)# print(v.query)
# 5. F,更新时用于获取原来的值from django.db.models import F,Q# models.UserInfo.objects.all().update(age=F("age")+1)


# 6. Q,用于构造复杂查询条件Q使用有两种方式:对象方式,方法方式# 应用一:对象方式# models.UserInfo.objects.filter(Q(id__gt=1))# models.UserInfo.objects.filter(Q(id=8) | Q(id=2))# models.UserInfo.objects.filter(Q(id=8) & Q(id=2))# 应用二:方法方式# q1 = Q()# q1.connector = 'OR'# q1.children.append(('id__gt', 1))# q1.children.append(('id', 10))# q1.children.append(('id', 9))### q2 = Q()# q2.connector = 'OR'# q2.children.append(('c1', 1))# q2.children.append(('c1', 10))# q2.children.append(('c1', 9))## q3 = Q()# q3.connector = 'AND'# q3.children.append(('id', 1))# q3.children.append(('id', 2))# q2.add(q3,'OR')## con = Q()# con.add(q1, 'AND')# con.add(q2, 'AND')
#例子    # 排序    # user_list = models.UserInfo.objects.all().order_by('-id','name')    # print(user_list)
   # 分组    from django.db.models import Count,Sum,Max,Min    # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id'))    # print(v.query)    # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)    # print(v.query)    # v =models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)    # print(v.query)    # 过滤    # models.UserInfo.objects.filter(id__gt=1)    # models.UserInfo.objects.filter(id__lt=1)    # models.UserInfo.objects.filter(id__lte=1)    # models.UserInfo.objects.filter(id__gte=1)    # models.UserInfo.objects.filter(id__in=[1,2,3])    # models.UserInfo.objects.filter(id__range=[1,2])    # models.UserInfo.objects.filter(name__startswith='xxxx')    # models.UserInfo.objects.filter(name__contains='xxxx')    # models.UserInfo.objects.exclude(id=1)
   # F,Q,extra    # from django.db.models import F    # models.UserInfo.objects.all().update(age=F("age")+1)
   # Q    # models.UserInfo.objects.filter(id=1,name='root')
   # condition = {    #     'id':1,    #     'name': 'root'    # }    # models.UserInfo.objects.filter(**condition)    # Q使用有两种方式:对象方式,方法方式*
   # from django.db.models import Q    # models.UserInfo.objects.filter(Q(id__gt=1))    # models.UserInfo.objects.filter(Q(id=8) | Q(id=2))    # models.UserInfo.objects.filter(Q(id=8) & Q(id=2))
    # q1 = Q()    # q1.connector = 'OR'    # q1.children.append(('id__gt', 1))    # q1.children.append(('id', 10))    # q1.children.append(('id', 9))    #    #    # q2 = Q()    # q2.connector = 'OR'    # q2.children.append(('c1', 1))    # q2.children.append(('c1', 10))    # q2.children.append(('c1', 9))    #    # q3 = Q()    # q3.connector = 'AND'    # q3.children.append(('id', 1))    # q3.children.append(('id', 2))    # q2.add(q3,'OR')    #    # con = Q()    # con.add(q1, 'AND')    # con.add(q2, 'AND')
   # condition_dict = {    #     'k1':[1,2,3,4],    #     'k2':[1,],    # }    # con = Q()    # for k,v in condition_dict.items():    #     q = Q()    #     q.connector = 'OR'    #     for i in v:    #         q.children.append(('id', i))    #     con.add(q,'AND')    # models.UserInfo.objects.filter(con)    #    # q1 = Q()    # q1.connector = 'OR'    # q1.children.append(('id', 1))    # q1.children.append(('id', 10))    # q1.children.append(('id', 9))    #    #    # q2 = Q()    # q2.connector = 'OR'    # q2.children.append(('c1', 1))    # q2.children.append(('c1', 10))    # q2.children.append(('c1', 9))    #    # q3 = Q()    # q3.connector = 'AND'    # q3.children.append(('id', 1))    # q3.children.append(('id', 2))    # q2.add(q3,'OR')    #    # con = Q()    # con.add(q1, 'AND')    # con.add(q2, 'AND')    # (id=1 or id = 10 or id=9 or (id=1 and id=2)) and (c1=1 or c1=10 or c1=9)


# 7. extra, 额外查询条件以及相关表,排序models.UserInfo.objects.filter(id__gt=1)models.UserInfo.objects.all() # id name age ut_idmodels.UserInfo.objects.extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)# a. 映射# select # select_params=None# select 此处 from 表# b. 条件# where=None# params=None,# select * from 表 where 此处# c. 表# tables# select * from 表,此处# c. 排序# order_by=None# select * from 表 order by 此处models.UserInfo.objects.extra(select={'newid':'select count(1) from app01_usertype where id>%s'},select_params=[1,],where = ['age>%s'],params=[18,],order_by=['-age'],tables=['app01_usertype'])"""select app01_userinfo.id,(select count(1) from app01_usertype where id>1) as newidfrom app01_userinfo,app01_usertypewhere app01_userinfo.age > 18order by app01_userinfo.age desc"""result = models.UserInfo.objects.filter(id__gt=1).extra(where=['app01_userinfo.id < %s'],params=[100,],tables=['app01_usertype'],order_by=['-app01_userinfo.id'],select={'uid':1,'sw':"select count(1) from app01_userinfo"})print(result.query)# SELECT (1) AS "uid", (select count(1) from app01_userinfo) AS "sw", "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age", "app01_userinfo"."ut_id" FROM "app01_userinfo" , "app01_usertype" WHERE ("app01_userinfo"."id" > 1 AND (app01_userinfo.id < 100)) ORDER BY ("app01_userinfo".id) DESC

# 8. 原生SQL语句from django.db import connection, connectionscursor = connection.cursor() # connection=default数据cursor = connections['db2'].cursor()           #setting中的database名称cursor.execute("""SELECT * from auth_user where id = %s""", [1])row = cursor.fetchone()row = cursor.fetchall()


  - 原生SQL语句- rawresult = models.UserInfo.objects.raw('select * from userinfo')[obj(UserInfo),obj,]result = models.UserInfo.objects.raw('select id,1 as name,2 as age,4 as ut_id from usertype')[obj(UserInfo),obj,]v1 = models.UserInfo.objects.raw('SELECT id,title FROM app01_usertype',translations=name_map)# 9. 简单的操作http://www.cnblogs.com/wupeiqi/articles/6216618.html

9 其他  http://www.cnblogs.com/wupeiqi/articles/6216618.html 其他操作    # v = models.UserInfo.objects.all().only('id','name')   # v = models.UserInfo.objects.all().defer('name') 除了name列

   models.UserInfo.objects.all().using('db2')   用哪个数据库  setting中database的   .
   models.UserInfo.objects.all().filter().all().exclude().only().defer() 可以一直去下去 因为是queryset类型的对象 有。方法,别的不行



分组  aggregate  distinct    # models.UserInfo.objects.none()    # result = models.UserInfo.objects.aggregate(k=Count('ut_id', distinct=True), n=Count('id'))    # print(result)
   #新增 返回的对象 就是新增的数据       # obj = models.UserType.objects.create(title='xxx')    # obj = models.UserType.objects.create(**{'title': 'xxx'})    # print(obj.id)
   save保存后才会数据库创建       # obj = models.UserType(title='xxx')    # obj.save()

    批量增加def bulk_create(self, objs, batch_size=None):    # 批量插入    # batch_size表示一次插入的个数    objs = [        models.DDD(name='r11'),        models.DDD(name='r22')    ]    models.DDD.objects.bulk_create(objs, 10)




def get_or_create(self, defaults=None, **kwargs):    # 如果存在,则获取,否则,创建    # defaults 指定创建时,其他字段的值    obj, created = models.UserInfo.objects.get_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 2})
   created 返回的为 True或者是false
def update_or_create(self, defaults=None, **kwargs):    # 如果存在,则更新,否则,创建    # defaults 指定创建时或更新时的其他字段    obj, created = models.UserInfo.objects.update_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 1})

   根据主键查询        # models.UserInfo.objects.filter(id__in=[1,2,3])    # models.UserInfo.objects.in_bulk([1,2,3])

==========================补充1==========================select_related   prefetch_related# q = models.UserInfo.objects.all()# select * from userinfo# select * from userinfo inner join usertype on ...# for row in q:#     print(row.name,row.ut.title)
# select_related: 查询主动做连表# q = models.UserInfo.objects.all().select_related('ut','gp')# select * from userinfo# select * from userinfo inner join usertype on ...# for row in q:#     print(row.name,row.ut.title)
# prefetch_related: 不做连表,做多次查询# q = models.UserInfo.objects.all().prefetch_related('ut')# select * from userinfo;# Django内部:ut_id = [2,4]# select * from usertype where id in [2,4]# for row in q:#     print(row.id,row.ut.title)

# 多对多    # objs = [    #     models.Boy(name='方少伟'),    #     models.Boy(name='由秦兵'),    #     models.Boy(name='陈涛'),    #     models.Boy(name='闫龙'),    #     models.Boy(name='吴彦祖'),    # ]    # models.Boy.objects.bulk_create(objs,5)    #    # objss = [    #     models.Girl(nick='小鱼'),    #     models.Girl(nick='小周'),    #     models.Girl(nick='小猫'),    #     models.Girl(nick='小狗'),    # ]    # models.Girl.objects.bulk_create(objss,5)
    # models.Love.objects.create(b_id=1,g_id=1)    # models.Love.objects.create(b_id=1,g_id=4)    # models.Love.objects.create(b_id=2,g_id=4)    # models.Love.objects.create(b_id=2,g_id=2)
    # 1. 和方少伟有关系的姑娘    # obj = models.Boy.objects.filter(name='方少伟').first()    # love_list = obj.love_set.all()    # for row in love_list:    #     print(row.g.nick)    #    #    # love_list = models.Love.objects.filter(b__name='方少伟')    # for row in love_list:    #     print(row.g.nick)    #    # love_list = models.Love.objects.filter(b__name='方少伟').values('g__nick')    # for item in love_list:    #     print(item['g__nick'])    #    # love_list = models.Love.objects.filter(b__name='方少伟').select_related('g')    # for obj in love_list:    #     print(obj.g.nick)


第三章关系表  可以自己定义类  或者使用内置的生成,但是只能生成三列,两者合用 # m = models.ManyToManyField('Boy')     生成第三张关系表

#m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g',)) 告诉django通过love连接,love表的b','g', 来关联 只提供查询和清空的功能

class Boy(models.Model):    name = models.CharField(max_length=32)    m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g',))

class Girl(models.Model):    nick = models.CharField(max_length=32)    # m = models.ManyToManyField('Boy')
class Love(models.Model):    b = models.ForeignKey('Boy')    g = models.ForeignKey('Girl')#联合唯一索引    class Meta:        unique_together = [            ('b','g'),        ]
    # obj = models.Boy.objects.filter(name='方少伟').first()    # print(obj.id,obj.name)    # obj.m.add(2)    # obj.m.add(2,4)    # obj.m.add(*[1,])
    # obj.m.remove(1)    # obj.m.remove(2,3)    # obj.m.remove(*[4,])
    # obj.m.set([1,])
    # q = obj.m.all()    # # [Girl对象]    # print(q)    # obj = models.Boy.objects.filter(name='方少伟').first()    # girl_list = obj.m.all()
    # obj = models.Boy.objects.filter(name='方少伟').first()    # girl_list = obj.m.all()    # girl_list = obj.m.filter(nick='小鱼')    # print(girl_list)
    # obj = models.Boy.objects.filter(name='方少伟').first()    # obj.m.clear()

    # obj = models.Girl.objects.filter(nick='小鱼').first()    # print(obj.id,obj.nick)    # v = obj.boy_set.all()    # print(v)
编写ORM  app01 -- models 中创建表ORM操作表:创建表修改表删除表操作数据行:增删改查ORM利用pymysql第三方工具连接数据库默认:SQLliteMySQL:mysql -> MySQLDB(修改django默认连接mySQL方式)

XSS 跨站脚本攻击 -慎用safe 和mark_safe(导入模块 )from django.utils.safestring import mark_safe
safe 在html中表明
-非要用,一定要过滤关键字

csrf   一般post提交的时候验证
FBv使用方法
a.基本应用 在form中添加 {% csrf_token %}    {{ csrf_token }} 页面会显示随机字符串信息
b. 全局禁用setting中 'django.middleware.csrf.CsrfViewMiddleware', 注释
c. 局部禁用 全局使用,在函数上添加装饰器 from django.views.decorators.csrf import csrf_exempt
@csrf_exemptdef index():passd.局部使用全局禁用 在函数上添加装饰器
from django.views.decorators.csrf import csrf_protect
@csrf_protectdef index():pass

CBV使用装饰器方法from django.views import Viewfrom django.utils.decorators import method_decorator
# 1. CBV应用装饰器def wrapper(func):    def inner(*args,**kwargs):        return func(*args,**kwargs)    return inner

# 1. 指定方法上添加装饰器
   # class Foo(View):    #    #     @method_decorator(csrf_protect)    #     def get(self,request):    #         pass    #    #     def post(self,request):    #         pass

# 2. 在类上添加#     @method_decorator(csrf_protect,name='dispatch')   #cbv中所有的提交都会先到dispatch #     class Foo(View):##         def get(self,request):#             pass##         def post(self,request):#             pass




Ajax提交数据时候,携带CSRF:a. 放置在data中携带<form method="POST" action="/csrf1.html">{% csrf_token %}<input id="user" type="text" name="user" /><input type="submit" value="提交"/><a onclick="submitForm();">Ajax提交</a></form><script src="/static/jquery-1.12.4.js"></script><script>function submitForm(){var csrf = $('input[name="csrfmiddlewaretoken"]').val();var user = $('#user').val();$.ajax({url: '/csrf1.html',type: 'POST',data: { "user":user,'csrfmiddlewaretoken': csrf},success:function(arg){console.log(arg);}})}
</script>b. 放在请求头中<form method="POST" action="/csrf1.html">{% csrf_token %}<input id="user" type="text" name="user" /><input type="submit" value="提交"/><a onclick="submitForm();">Ajax提交</a></form><script src="/static/jquery-1.12.4.js"></script><script src="/static/jquery.cookie.js"></script>
<script>function submitForm(){var token = $.cookie('csrftoken');var user = $('#user').val();$.ajax({url: '/csrf1.html',type: 'POST',headers:{'X-CSRFToken': token},data: { "user":user},success:function(arg){console.log(arg);}})}</script>


django视图 cbv 、 fbv
CBV先dispatch 判断method 反射如果想做定制化的 可以添加在这里
       def dispatch(self, request, *args, **kwargs):        print("before")        obj=super(Login, self).dispatch(request,*args,**kwargs)        print("after")        return obj
url中设置re_path('classes/',views.Login.as_view),固定用法
view设置为form表单只有post 和 get 方法,ajex 支持所有from django.views import Viewclass Login(View):    '''    请求方法基本常用的    get  查询    post 创建    put  更新    delete 删除    '''
       def dispatch(self, request, *args, **kwargs):        print("before")        obj=super(Login, self).dispatch(request,*args,**kwargs)        print("after")        return obj
   def get(self,request):        pass
   def put(self,request):        pass






django 分页操作分批获取数据models.UserInfo.objects.all()[0:10]models.UserInfo.objects.all()[10:20]



---django  自带提供的的分页
from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage
def index(request):    """    分页    :param request:    :return:    """    # for i in range(300):    #     name = "root" + str(i)    #     models.UserInfo.objects.create(name=name,age=18,ut_id=1)

   current_page = request.GET.get('page')
   user_list = models.UserInfo.objects.all()    paginator = Paginator(user_list,10)    # per_page: 每页显示条目数量    # count:    数据总个数    # num_pages:总页数    # page_range:总页数的索引范围,如: (1,10),(1,200)    # page:     page对象    try:        posts = paginator.page(current_page)    except PageNotAnInteger as e:        posts = paginator.page(1)    except EmptyPage as e:        posts = paginator.page(1)    # has_next              是否有下一页    # next_page_number      下一页页码    # has_previous          是否有上一页    # previous_page_number  上一页页码    # object_list           分页之后的数据列表    # number                当前页    # paginator             paginator对象    return render(request,'index.html',{'posts':posts})

--自定义分页组件
from utils.pager import PageInfodef custom(request):    # 表示用户当前想要访问的页码: 8
   all_count = models.UserInfo.objects.all().count()
   page_info = PageInfo(request.GET.get('page'),all_count,10,'/custom.html',11)    user_list = models.UserInfo.objects.all()[page_info.start():page_info.end()]
   return render(request,'custom.html',{'user_list':user_list,'page_info':page_info})

class PageInfo(object):
   def __init__(self,current_page,all_count,per_page,base_url,show_page=11):        """
       :param current_page:        :param all_count: 数据库总行数        :param per_page: 每页显示函数        :return:        """        try:            self.current_page = int(current_page)        except Exception as e:            self.current_page = 1        self.per_page = per_page
       a,b = divmod(all_count,per_page)        if b:            a = a +1        self.all_pager = a        self.show_page = show_page        self.base_url = base_url    def start(self):        return (self.current_page-1) * self.per_page
   def end(self):        return self.current_page * self.per_page

   def pager(self):        # v = "<a href='/custom.html?page=1'>1</a><a href='/custom.html?page=2'>2</a>"        # return v        page_list = []
       half = int((self.show_page-1)/2)
       # 如果数据总页数 < 11        if self.all_pager < self.show_page:            begin = 1            stop = self.all_pager + 1        # 如果数据总页数 > 11        else:            # 如果当前页 <=5,永远显示1,11            if self.current_page <= half:                begin = 1                stop = self.show_page + 1            else:                if self.current_page + half > self.all_pager:                    begin = self.all_pager - self.show_page + 1                    stop = self.all_pager + 1                else:                    begin = self.current_page - half                    stop = self.current_page + half + 1
       if self.current_page <= 1:            prev = "<li><a href='#'>上一页</a></li>"        else:            prev = "<li><a href='%s?page=%s'>上一页</a></li>" %(self.base_url,self.current_page-1,)        page_list.append(prev)
       for i in range(begin,stop):            if i == self.current_page:                temp = "<li class='active'><a  href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,)            else:                temp = "<li><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,)            page_list.append(temp)
       if self.current_page >= self.all_pager:            nex = "<li><a href='#'>下一页</a></li>"        else:            nex = "<li><a href='%s?page=%s'>下一页</a></li>" %(self.base_url,self.current_page+1,)        page_list.append(nex)

       return ''.join(page_list)

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title></title>    <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" /></head><body>    <h1>用户列表</h1>    <ul>        {% for row in user_list %}            <li>{{ row.name }}</li>        {% endfor %}    </ul>
   <nav aria-label="Page navigation">      <ul class="pagination">          {{ page_info.pager|safe }}      </ul>    </nav></body></html>

原文地址:https://www.cnblogs.com/polly-ling/p/9350136.html