• day-63Django


    ORM一对一

        列子:
                
                用户表(母表):
                    id    name   age   
                    1     zekai   18
                
            
                
                薪水表(子表):
                    id    money   us_id
                     1      2000     1          #1这个id只能出现一次
            
            class UserInfo(models.Model):
                name = models.CharField(max_length=32)
                age = models.CharField(max_length=32)
                
            
            class Salary(models.Model):
                money = models.CharField(max_length=32)
                us = models.OneToOneField("UserInfo")
            
            
            一对一:
                #增加:
                # models.UserInfo.objects.create(name='zekai', age=18)
                
                # 查询:
                # 正向查询(子表查母表):
                # 1.11.22版本 :res.us.name
                # 1.11.10版本 : res.母表表名小写.name
                res = models.Salary.objects.filter(money="3000").first()
                print(res.us.name)
    
    
                # 反向查询(母表查子表)
                # obj.子表小写.子表列名 
                res = models.UserInfo.objects.filter(name='zekai').first()
                print(res.salary.money)

    Django列类型与参数

                mysql                                      django
                                
                            tinyint                                         无
                            smallint(unsigned)        SmallIntegerField (PositiveSmallIntegerField)           括号里面表示无负号
                    数字    int (unsigned))             IntegerField   (PositiveIntegerField)
                            mediumint                                    无
                            bigint(unsigned)                    BigIntegerField                                           没有无负号单词
                            
                            float                                  FloatField
                            decimal(5,2) : 200.23                  DecimalField
                            小数点后面2位,总共5位
                            
                            char                                        无
                    字符串    varchar                                 CharFiled
                            text                                    TextField
                            
                            
                    时间     datetime (2019-7-17 12:23:34)        DateTimeField        
                             date      (2019-7-17)                  DateField
                             
                         
                    - 参数:
                        max_length=32        字符串最大长度
                        null=True  :        可以设置为null
                        db_index=True :     设置索引
                        default :           设置默认值
                        unique :            设置唯一索引
                        db_column:           在表中重新取一个名字
                        unique_together:     联合唯一索引
                        index_together :    普通联合索引
                        
                        案例:
                            class xxx():
                                表模型类
                                
                                class Meta:
                                    unique_together = (
                                        ('money', 'us_id'),
                                        ....
                                    )
                                    index_together = (
                                        ('money', 'us_id')
                                        ....
                                    )
                

    Django-admin列类型与参数

    djagno-admin:
        django自带的管理后台系统
        
    用户名、密码命令生成:
        python3 manage.py  createsuperuser
        
    如何管理自己生成的表:  
        每个app下admin文件中导入模型:
            from app01 import models
            admin.site.register(models.UserInfo)
            
        下面都是在django-admin中生效
        
            django-admin中的列类型:
                EmailField(CharField):
                    - 字符串类型,Django Admin以及ModelForm中提供验证机制
                IPAddressField(Field)
                    - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
                GenericIPAddressField(Field)
                    - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
                    - 参数:
                        protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
                        unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both"
                URLField(CharField)
                    - 字符串类型,Django Admin以及ModelForm中提供验证 URL
                SlugField(CharField)
                    - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
                CommaSeparatedIntegerField(CharField)
                    - 字符串类型,格式必须为逗号分割的数字
                UUIDField(Field)
                    - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
                FileField(Field)
        
            djagno-admin中的参数 :
                verbose_name        Admin中显示的字段名称            
                blank               Admin中是否允许用户输入为空
                editable            Admin中是否可以隐藏
                help_text           Admin中该字段的提示信息
                choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
                
                choices = (
                    (1, ''),
                    (2, '')
                                    #1是mysql表现形式   男女是djagno-admin表现形式
                )
                gender = models.IntegerField(choices=chocies)
                
            
                
                 from django.core.validators import RegexValidator
                 
                 test3 = models.CharField(
                     max_length=32,
                     error_messages={                       #优先级,先c1再mes
                         'c1': '优先错信息1',
                         'c2': '优先错信息2',
                        'c3': '优先错信息3',
                     },
                     validators=[RegexValidator(regex='root_d+', message='错误了', code='c1')]
                )

    Django内置分页

    def index(request):
        from django,core,paginator import Paginator,EmptyPage(用户点击页数超出页面总页面数,用万能异常能捕获到·)
    
     1. 接收页数 
     
        try:
         cur_page = request.GET.get('cur_page')             #接收的是用户点击的第几页
            cur_page = int(cur_page)               #强行报错
        except Exception as e:
            cur_page = 1
    
        user_list = models.UserInfo.objects.all()
      
    
     2.拿到页数数据 
     
        paginator = Paginator(user_list, 10)                #括号里边是(列表套对象,每页多少条数据)
        
        #paginator这个对象有下面这些方法:
        
        # per_page:                     每页显示多少条数据
        # count:                        传过来数据总个数(多少条)
        # num_pages:                    一共能显示多少页
        # page_range:                   一共能显示多少页索引范围,如: 索引范围是1到10 ,就是翻页能从1点到10
        # page:                         后面点page能获得page的方法,如下
        
        
     3.发送到html
        users = paginator.page(cur_page)                    #参数是用户点击的第几页,而users就是用户点击的第几页的所有数据
        
      
        #users的方法:
        
        # has_next                      是否有下一页
        # next_page_number              获取下一页页码
        # has_previous                  是否有上一页
        # previous_page_number          获取上一页页码
        # object_list                   用户点击的第几页的数据列表
        # number                        当前页码
        # paginator                     又可以点paginator对象,获得paginator的方法
        
        
        return render(request, "index.html", {"user_list":users})
        
     4.在html使用方法 
            #users传到html后,就可以在html点上面的所有方法

    html代码:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>Title</title>
    </head>
    <body>
        <ul>
            {% for user in user_list.object_list %}
                <li>{{ user.name }}</li>
            {% endfor %}
        </ul>
    
        {% if user_list.has_previous %}
            <a href="/index/?cur_page={{ user_list.previous_page_number }}">上一页</a>
        {% endif %}
    
        {% for num in user_list.paginator.page_range %}
            
                <a  href="/index/?cur_page={{ num }}">{{ num }}</a>
                           
        {% endfor %}
    
        {% if user_list.has_next %}
            <a href="/index/?cur_page={{ user_list.next_page_number }}">下一页</a>
        {% endif %}
    
    
    
    </body>
    </html>

    手写分页

    # 自定制的分页类
    class PageInfo():
        def __init__(self, cur_page, total, per_page=10, show_page=11):
                            
                            
            cur_page        用户点击的第多少页         
                           
            total           表有多少条数据     
            
            per_page        每页多少条数据
            
            show_page       显示当前页数一共为11页
            
            
            try:
                self.cur_page = int(cur_page)
            except  Exception as e:                                 #如果传入不是数字强行报错
                self.cur_page = 1
    
            self.per_page = per_page
            self.show_page = show_page
            
    
            a, b = divmod(total, per_page)                          #前面整除的数字,后面是余数的数字(301,10)=>(30,1)
            if b:
                self.total_page = a + 1                             #定义一个self.total_page(总页数)
            else:
                self.total_page = a
                
    
        def get_start(self):                                        #切片的开始位置
            return (self.cur_page - 1) * self.per_page
    
        def get_stop(self):                                         #切片的接收位置
            return  self.cur_page * self.per_page
            
            
            
    
        def page(self):                                             #拼接自己写好的html标签
    
            half = int((self.show_page ) / 2)                       #为了区分点击两边的区域
    
    
          
            if self.total_page < self.show_page:                    #要显示的页数小于要展示的页数show_page(数据太少)
                begin = 1
                stop = self.total_page + 1
                
                
            else:
                # 下面代码可以自定义,比如:begin = self.cur_page  - half
                # 显示效果是左右越点越少
                
                
                if self.cur_page - 1 < half:                        #靠最左边点击会出现负数的情况
                    begin = 1
                    stop = self.show_page + 1
                    
                elif self.cur_page + half > self.total_page:        #靠最右边点击会出现超出页数的情况
                    begin = self.total_page - self.show_page + 1
                    stop = self.total_page + 1
                    
                else:                                               #正常显示数据
                    begin = self.cur_page - half
                    stop = self.cur_page  + half + 1
    
            sli = []        
            if self.cur_page == 1:                                   #如果上一页一直点到第一页,在点会出现负数并报错,所以用#让它处在第一页
                s =  "<li class='disabled'><a href='#'>上一页</a></li>"
            else:
                s =  "<li><a   href='/custom/?cur_page=%s'>上一页</a></li>" %(self.cur_page - 1)  #没有上述情况,就进行跳转
    
            sli.append(s)
    
            for num in range(begin, stop):                                                         #为了显示高亮
                if num == self.cur_page:
                    s = "<li class='active'><a   href='/custom/?cur_page=%s'>%s</a></li>" %(num, num)
                else:
                    s = "<li><a   href='/custom/?cur_page=%s'>%s</a></li>" %(num, num)
                sli.append(s)
    
            if self.cur_page == self.total_page:                                                   #作用同上一页一样
                s = "<li  class='disabled'><a  href='#'>下一页</a></li>"
            else:
                s = "<li><a  href='/custom/?cur_page=%s'>下一页</a></li>" % (self.cur_page + 1)
            sli.append(s)
    
            page_str = " ".join(sli)                                                               #在列表中,把逗号换成空,返回一个字符串
    
            return page_str

    # 自定制的分页函数

        def custom(request):

          cur_page = request.GET.get('cur_page')                             #用户点击的第几页(一开始需要自己来传)

          total = models.UserInfo.objects.count() 
          pageinfo = PageInfo(cur_page, total)
          start = pageinfo.get_start()
          stop = pageinfo.get_stop()
          user_list = models.UserInfo.objects.all()[start:stop]

          return render(request, "custom.html",{"user_list":user_list, "pageinfo":pageinfo})    #将对象传入html,在html中可以使用点方法

    #推导理论

     cur_page start stop
     1     0   10
     2     10   20
     3     20   30
     n  (n-1)*per_page  n * per_page

    html代码(需要bs引入):

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>Title</title>
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
     integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    </head>
    <body>
        <ul>
            {% for user in user_list %}
    
                <li>{{ user.name }}</li>
            {% endfor %}
        </ul>
    
    
    
        <nav aria-label="Page navigation">
          <ul class="pagination">
            {{ pageinfo.page | safe }}
          </ul>
    </nav>
    </body>
    </html>

    CSRF:

      跨站请求伪造

      原理:在对方使用的浏览器上拿到对方的cookie,使用这个cookie进行对对方访问过的网站,进行访问和操作
      造成原因:用户使用同一个浏览器打开两个网站,第一个网站状态还没有退出,
             而第二个网站不受信用,如果在第二个网站进行操作,就有可能受到攻击
      解决方案:浏览器在请求服务器的时候,服务器除了返回数据和cookie,还在返回了token,
             而tokin放在发的html中的form表单,下次再次访问,会和服务器存的token进行比对,不一样拒绝访问
      不同之处:tokin一般获取不到,而cookie可以,并且tokin要先于cookie传入浏览器

     中间件开启的时候,表示开启全局的csrf验证(token验证):
                
                HTML处理方法
                        1. 在form表单中生成cookie
                        <form>
                            {% csrf_token %}        在form表单中生成cookie
                            <input type='text'>
                        </form>
                
                
                
            
                    
                FBV处理方法    
                        1..下面函数关闭csrf验证
                        from django.views.decorators.csrf import csrf_exempt                    
                        @csrf_exempt
                        def csrf1(request):
                            if request.method == 'GET':
                                return render(request, 'csrf1.html')
                            else:
                                return HttpResponse('ok')
                    
                
                
     当中间件关闭的时候:
                        1.下面函数开启csrf验证
                        from django.views.decorators.csrf import csrf_protect                    
                        @csrf_protect
                        def csrf1(request):
                            if request.method == 'GET':
                                return render(request, 'csrf1.html')
                            else:
                                return HttpResponse('ok')
                
                
            
                CBV处理方法:
                        from django.utils.decorators import method_decorator
                        @method_decorator(csrf_protect, name='get')
                                        #里面第一个是上述开启或关闭方法,第二个是对哪个请求有作用,也可以不写
                        class User(View):
                            def get(self, request):
                                pass
                            def post(self, request):
                                pass
                                
              
                ajax处理方法:
                    csrftoken = $('input[name="csrfmiddlewaretoken"]').val()    #属性选择器
                    $.ajax({
                        type:"POST",
                        url : '/xxxx/',
                        data: {"name":'xxxx'},
                        headers : {'X-CSRFToken': token},                       #自己获取表单的token,放进去发送                                  
                        success: function(){
                            console.log(data)
                        }
                    })
  • 相关阅读:
    利用nginx实现负载均衡和动静分离
    Nginx动静分离实现
    php中session 入库的实现
    php文字水印和php图片水印实现代码(二种加水印方法)
    采集图片水印添加
    [安全]PHP能引起安全的函数
    [安全]服务器安全之 PHP权限目录
    Centos下安装git的web服务器
    Centos下抓包
    UVA 10795
  • 原文地址:https://www.cnblogs.com/klw1/p/11202306.html
Copyright © 2020-2023  润新知