• Python-Django进阶


    1. 路由系统

    • 浏览器会自动给url后加一个“/”
    • django会自动给路由的正则表达式前面加一个“/”
    • django会给任何不带“/”结尾的url语句添加“/”(可设置)
    • 短路路由规则:匹配到第一条就忽略后面所有!
    • 所以路由顺序很重要!

    1.1 普通路由

    url(r'^index/', views.index),
    

    1.2 正则路由

    url(r'^page/d+', views.page),
    

    1.3 正则加括号

    可以提供参数传递,按顺序接收,接收到的都是字符串

    # urls.py
    url(r'^page/(d+)', views.page),
    
    # views.py
    def page(request, index):
    page = index
    return HttpResponse("page: 第%s页" % page)
    

    1.4 正则加括号加指定参数名

    提供指定参数传递,按参数名字进行接收,顺序可变,但参数名必须相同,接收到的都是字符串。

    urls.py

    url(r'^page/(?P<page>d+)/(?P<number>d+)', views.page),
    

    views.py

    def page(request, page, number):
    p = page
    n = number
    return HttpResponse("page: 第%s页 第%s条" %(p, n))
    

    1.5 分级路由include

    在 APP01 中新建urls文件

    from django.conf.urls import include
    url(r'index/', include(app01.urls)),
    

    2. 模版系统

    在html文件中使用模板语言

    2.1 普通变量

    {{var}}
    

    调用数组元素:(圆点加下标)

    list1 = [1,2,3]
    {{list.0}}
    {{list.1}}
    {{list.2}}
    

    调用字典元素: (圆点加键值)

    dict1 = {"k1":"v1","k2":"v2"}
    {{dict1.k1}}
    {{dict1.k2}}
    

    2.2 if 语句

    在结构体内引用变量,不需要再加双大括号

    {% if 判断 %}
    ......
    {% else %} 
    ......
    {% endif %}
    

    2.3 for循环

    {% for i in data %}
    ......
    {% endfor %}
    

    django内置特殊的用于for循环的变量:

    forloop.counter
    forloop.counter0
    forloop.first
    forloop.last 
    

    2.4 内置函数

    lower    first    last    divisibleby等等。例如:
    {{ “AAA”|lower}}    
    使用管道符引用函数名,左边的‘AAA’自动当作参数传递给lower函数
    又或:判断当前循环的次数是否能被2整除
    {% if forloop.counter0|divisibleby:"2" %}
        <tr class="success">
    {% else %}
        <tr>
    {% endif %}   
    

    2.5 自定义函数

    templatetags
    register
    simple_tag
    filter等等……
    忘记它吧……
    

    2.6 继承模板

    {% extends "xxxx.html" %}
    

    2.7 重写模板

    在母版和子版式中使用同样的:
    {% block 取个名字 %}
        (每个子版专属的代码)
    {% endbloack %}
    

    2.8 导入html代码

    {% include "xx.html" %}
    

    与继承模板不同的是,导入的是xxx.html的完全代码,因此xxx.html中最好没有头部,title等代码,只有实际的功能代码。

    3. 模型(model)

    3.1 类结构

    3.1.1 基础类型

    from django.db import models
    
    class userinfo(models.Model):
        name = models.CharField(max_length=30)
        email = models.EmailField()
        memo = models.TextField()
    

    3.1.2 连表类型

    一对多:models.ForeignKey("其他表")
    多对多:models.ManyToManyField("其他表")
    一对一:models.OneToOneField("其他表")
    

    3.1.3 字段类型

    1. models.AutoField  
    • 自增列 = int(11)
    • 如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
    1. models.CharField  

    字符串字段,必须 max_length 参数

    1. models.BooleanField  

    布尔类型=tinyint(1),不能为空,Blank=True

    1. models.ComaSeparatedIntegerField  

    用逗号分割的数字=varchar,继承CharField,所以必须 max_lenght 参数

    1. models.DateField  

    日期类型 date,对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。

    1. models.DateTimeField  

    日期类型 datetime,同DateField的参数

    1. models.Decimal  

    十进制小数类型 = decimal,必须指定整数位max_digits和小数位decimal_places

    1. models.EmailField  

    字符串类型(正则表达式邮箱) =varchar,对字符串进行正则表达式

    1. models.FloatField  浮点类型 = double

    2. models.IntegerField  整形

    3. models.BigIntegerField  长整形

    integer_field_ranges = {
      'SmallIntegerField': (-32768, 32767),
     'IntegerField': (-2147483648, 2147483647),
      'BigIntegerField': (-9223372036854775808, 9223372036854775807),
      'PositiveSmallIntegerField': (0, 32767),
      'PositiveIntegerField': (0, 2147483647),
    }
    
    1. models.IPAddressField  字符串类型(ip4正则表达式)

    2. models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)

    参数protocol可以是:both、ipv4、ipv6,验证时,会根据设置报错

    1. models.NullBooleanField  允许为空的布尔类型

    2. models.PositiveIntegerFiel  正Integer

    3. models.PositiveSmallIntegerField  正smallInteger

    4. models.SlugField  减号、下划线、字母、数字

    5. models.SmallIntegerField  数字

    数据库中的字段有:tinyint、smallint、int、bigint

    1. models.TextField  字符串=longtext

    2. models.TimeField  时间 HH:MM[:ss[.uuuuuu]]

    3. models.URLField  字符串,地址正则表达式

    4. models.BinaryField  二进制

    5. models.ImageField 图片

    6. models.FilePathField 文件

    3.1.4 参数类型

    1、null=True
      数据库中字段是否可以为空
    2、blank=True
      django的 Admin 中添加数据时是否可允许空值
    3、primary_key = False
      主键,对AutoField设置主键后,就会代替原来的自增 id 列
    4、auto_now 和 auto_now_add
      auto_now   自动创建---无论添加或修改,都是当前操作的时间
      auto_now_add  自动创建---永远是创建时的时间
    5、choices
    GENDER_CHOICE = (
            (u'M', u'Male'),
            (u'F', u'Female'),
        )
    gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
    6、max_length
    7、default  默认值
    8、verbose_name  Admin中字段的显示名称
    9、name|db_column  数据库中的字段名称
    10、unique=True  不允许重复
    11、db_index = True  数据库索引
    12、editable=True  在Admin里是否可编辑
    13、error_messages=None  错误提示
    14、auto_created=False  自动创建
    15、help_text  在Admin中提示帮助信息
    16、validators=[]
    17、upload-to
    

    3.1.5 Python3 下使用MySQL

    settings:

    配置

    DATABASES = {
        'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'django01',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '192.168.92.201',
        'PORT': '3306',
        }
    }
    

    注册APP:

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'pga',
    ]
    

    注意:由于Python3不支持MySQLdb(),需要以pycharm替代,在project的__init__.py中:

    import pymysql
    pymysql.install_as_MySQLdb()
    

    3.2 表操作

    3.2.1 基本操作

      # 增
        #
        # models.Tb1.objects.create(c1='xx', c2='oo')  增加一条数据,可以接受字典类型数据 **kwargs
    
        # obj = models.Tb1(c1='xx', c2='oo')
        # obj.save()
    
        # 查
        #
        # models.Tb1.objects.get(id=123)         # 获取单条数据,不存在则报错(不建议)
        # models.Tb1.objects.all()               # 获取全部
        # models.Tb1.objects.filter(name='seven') # 获取指定条件的数据
    
        # 删
        #
        # models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据
    
        # 改
        # models.Tb1.objects.filter(name='seven').update(gender='0')  # 将指定条件的数据更新,均支持 **kwargs
        # obj = models.Tb1.objects.get(id=1)
        # obj.c1 = '111'
        # obj.save()                                                 # 修改单条数据
    

    3.2.2 进阶操作

    利用双下划线将字段和对应的操作连接起来

    # 获取个数
            #
            # models.Tb1.objects.filter(name='seven').count()
    
            # 大于,小于
            #
            # models.Tb1.objects.filter(id__gt=1)              # 获取id大于1的值
            # models.Tb1.objects.filter(id__gte=1)              # 获取id大于等于1的值
            # models.Tb1.objects.filter(id__lt=10)             # 获取id小于10的值
            # models.Tb1.objects.filter(id__lte=10)             # 获取id小于10的值
            # models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值
    
            # in
            #
            # models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
            # models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
    
            # isnull
            # Entry.objects.filter(pub_date__isnull=True)
    
            # contains
            #
            # models.Tb1.objects.filter(name__contains="ven")
            # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
            # models.Tb1.objects.exclude(name__icontains="ven")
    
            # range
            #
            # models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and
    
            # 其他类似
            #
            # startswith,istartswith, endswith, iendswith,
    
            # order by
            #
            # models.Tb1.objects.filter(name='seven').order_by('id')    # asc
            # models.Tb1.objects.filter(name='seven').order_by('-id')   # desc
    
            # group by
            #
            # from django.db.models import Count, Min, Max, Sum
            # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
            # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
    
            # limit 、offset
            #
            # models.Tb1.objects.all()[10:20]
    
            # regex正则匹配,iregex 不区分大小写
            #
            # Entry.objects.get(title__regex=r'^(An?|The) +')
            # Entry.objects.get(title__iregex=r'^(an?|the) +')
    
            # date
            #
            # Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
            # Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))
    
            # year
            #
            # Entry.objects.filter(pub_date__year=2005)
            # Entry.objects.filter(pub_date__year__gte=2005)
    
            # month
            #
            # Entry.objects.filter(pub_date__month=12)
            # Entry.objects.filter(pub_date__month__gte=6)
    
            # day
            #
            # Entry.objects.filter(pub_date__day=3)
            # Entry.objects.filter(pub_date__day__gte=3)
    
            # week_day
            #
            # Entry.objects.filter(pub_date__week_day=2)
            # Entry.objects.filter(pub_date__week_day__gte=2)
    
            # hour
            #
            # Event.objects.filter(timestamp__hour=23)
            # Event.objects.filter(time__hour=5)
            # Event.objects.filter(timestamp__hour__gte=12)
    
            # minute
            #
            # Event.objects.filter(timestamp__minute=29)
            # Event.objects.filter(time__minute=46)
            # Event.objects.filter(timestamp__minute__gte=29)
    
            # second
            #
            # Event.objects.filter(timestamp__second=31)
            # Event.objects.filter(time__second=2)
            # Event.objects.filter(timestamp__second__gte=31)
    
    

    其他操作补充:

    # extra
        #
        # extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
        #    Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
        #    Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
        #    Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
        #    Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
    
        # F
        #
        # from django.db.models import F
        # models.Tb1.objects.update(num=F('num')+1)
    
    
        # Q
        #
        # 方式一:
        # Q(nid__gt=10)
        # Q(nid=8) | Q(nid__gt=10)
        # Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
        # 方式二:
        # con = Q()
        # 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))
        # con.add(q1, 'AND')
        # con.add(q2, 'AND')
        #
        # models.Tb1.objects.filter(con)
    
    
        # 执行原生SQL
        #
        # from django.db import connection, connections
        # cursor = connection.cursor()  # cursor = connections['default'].cursor()
        # cursor.execute("""SELECT * from auth_user where id = %s""", [1])
        # row = cursor.fetchone()
    

    3.2.3 连表操作

    利用双下划线和 _set 将表之间的操作连接起来

    表结构实例

    class UserProfile(models.Model):
        user_info = models.OneToOneField('UserInfo')
        username = models.CharField(max_length=64)
        password = models.CharField(max_length=64)
    
        def __unicode__(self):
            return self.username
    
    
    class UserInfo(models.Model):
        user_type_choice = (
            (0, u'普通用户'),
            (1, u'高级用户'),
        )
        user_type = models.IntegerField(choices=user_type_choice)
        name = models.CharField(max_length=32)
        email = models.CharField(max_length=32)
        address = models.CharField(max_length=128)
    
        def __unicode__(self):
            return self.name
    
    
    class UserGroup(models.Model):
    
        caption = models.CharField(max_length=64)
    
        user_info = models.ManyToManyField('UserInfo')
    
        def __unicode__(self):
            return self.caption
    
    
    class Host(models.Model):
        hostname = models.CharField(max_length=64)
        ip = models.GenericIPAddressField()
        user_group = models.ForeignKey('UserGroup')
    
        def __unicode__(self):
            return self.hostname
    

    一对一操作

    user_info_obj = models.UserInfo.objects.filter(id=1).first()
    print user_info_obj.user_type
    print user_info_obj.get_user_type_display()
    print user_info_obj.userprofile.password
     
    user_info_obj = models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()
    print user_info_obj.keys()
    print user_info_obj.values()
    

    一对多操作

    类似一对一
    1、搜索条件使用 __ 连接
    2、获取值时使用 .    连接
    

    多对多操作

    user_info_obj = models.UserInfo.objects.get(name=u'Dave')
    user_info_objs = models.UserInfo.objects.all()
     
    group_obj = models.UserGroup.objects.get(caption='CEO')
    group_objs = models.UserGroup.objects.all()
     
    # 添加数据
    #group_obj.user_info.add(user_info_obj)
    #group_obj.user_info.add(*user_info_objs)
     
    # 删除数据
    #group_obj.user_info.remove(user_info_obj)
    #group_obj.user_info.remove(*user_info_objs)
     
    # 添加数据
    #user_info_obj.usergroup_set.add(group_obj)
    #user_info_obj.usergroup_set.add(*group_objs)
     
    # 删除数据
    #user_info_obj.usergroup_set.remove(group_obj)
    #user_info_obj.usergroup_set.remove(*group_objs)
     
    # 获取数据
    #print group_obj.user_info.all()
    #print group_obj.user_info.all().filter(id=1)
     
    # 获取数据
    #print user_info_obj.usergroup_set.all()
    #print user_info_obj.usergroup_set.all().filter(caption='CEO')
    #print user_info_obj.usergroup_set.all().filter(caption='DBA')
    

    4. 跨站请求伪造

    一、简介

    django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。

    全局:

      中间件 django.middleware.csrf.CsrfViewMiddleware

    局部:

    @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
    @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
    注:from django.views.decorators.csrf import csrf_exempt,csrf_protect

    二、应用

    1、普通表单

    veiw中设置返回值:
      return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))  
         或者
         return render(request, 'xxx.html', data)
      
    html中设置Token:
      {% csrf_token %}
    

    2、Ajax

    对于传统的form,可以通过表单的方式将token再次发送到服务端,而对于ajax的话,使用如下方式。

    view.py

    from django.template.context import RequestContext
    # Create your views here.
      
      
    def test(request):
      
        if request.method == 'POST':
            print request.POST
            return HttpResponse('ok')
        return  render_to_response('app01/test.html',context_instance=RequestContext(request))
    

    text.html

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        {% csrf_token %}
      
        <input type="button" onclick="Do();"  value="Do it"/>
      
        <script src="/static/plugin/jquery/jquery-1.8.0.js"></script>
        <script src="/static/plugin/jquery/jquery.cookie.js"></script>
        <script type="text/javascript">
            var csrftoken = $.cookie('csrftoken');
      
            function csrfSafeMethod(method) {
                // these HTTP methods do not require CSRF protection
                return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
            }
            $.ajaxSetup({
                beforeSend: function(xhr, settings) {
                    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                        xhr.setRequestHeader("X-CSRFToken", csrftoken);
                    }
                }
            });
            function Do(){
      
                $.ajax({
                    url:"/app01/test/",
                    data:{id:1},
                    type:'POST',
                    success:function(data){
                        console.log(data);
                    }
                });
      
            }
        </script>
    </body>
    </html>
    

    更多:https://docs.djangoproject.com/en/dev/ref/csrf/#ajax

  • 相关阅读:
    78. Subsets
    93. Restore IP Addresses
    71. Simplify Path
    82. Remove Duplicates from Sorted List II
    95. Unique Binary Search Trees II
    96. Unique Binary Search Trees
    312. Burst Balloons
    程序员社交平台
    APP Store开发指南
    iOS框架搭建(MVC,自定义TabBar)--微博搭建为例
  • 原文地址:https://www.cnblogs.com/huyuedong/p/6213762.html
Copyright © 2020-2023  润新知