Django 0.6

今日内容

  1. 模版语言剩下的

http://www.cnblogs.com/liwenzhou/p/7931828.html

  1. csrf_token: 用于跨站请求伪造保护。是Django提供的一个解决方案:在提交表单时带着之前Django给该页面生成的token,如果没有token,或token匹配失败,将拒绝继续访问;这样,钓鱼网站就不可以通过单单设置action,而跳转至正经网站某个页面,进而修改正经网站的数据库。

在页面的form表单里面写上{% csrf_token %},在settings中即可不注释csrf相关

 

#钓鱼网站html

<h1>这是一个钓鱼网站</h1>

<formaction="http://127.0.0.1:8000/zhuanzhang/"method="post">

# action直接跳转到别的网站

    <p>转给谁:<input type="text"></p>

    <p><input style="display: none" type="text" name="id" value="3"></p>

    <p>转多少:<input type="text" name="num"></p>

    <p>密码:<input type="password" name="pwd"></p>

    <p><input type="submit" value="提交"></p>

</form>

 

#正经网站html

<h1>这是一个正经网站</h1>

<formaction="/zhuanzhang/"method="post">

    {% csrf_token %}  # 阻止跨站请求伪造

    <p>转给谁:<input type="text" name="id"></p>

    <p>转多少:<input type="text" name="num"></p>

    <p>密码:<input type="password" name="pwd"></p>

    <p><input type="submit" value="提交"></p>

</form>

 

   ps:如果不设置数据库,使用默认的数据库db.sqlite3

 

  1. 静态文件相关(取代硬编码(/static/…))

如果有改static这个名字的需求,用硬编码要通篇改;如果使用以下方式,则不存在这个问题;一般来说,上述需求比较不常见

{% load static %}

<img src="{% static "images/hi.jpg" %}" alt="Hi!" />

 

引用JS文件时使用:

{% load static %}

<script src="{% static "mytest.js" %}"></script>

 

某个文件多处被用到可以存为一个变量

{% load static %}

{% static "images/hi.jpg" as myphoto %}

<img src="{{ myphoto }}"></img>

 

  1. get_static_prefix

# 极少使用

{% load static %}

<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />

 

{% load static %}

{% get_static_prefix as STATIC_PREFIX %}

<img src="{{ STATIC_PREFIX }}images/hi.jpg"alt="Hi!" />

<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />

 

  1. 自定义simpletag和自定义filter类似,只不过接收更灵活的参数。

自定义的filter,simpletag和inclusion_tag都要放在templatetags 这个新建的package中的py文件下

filter: {{ }}   在变量的基础上做额外的调整

simpletag  {% %}  可传多个参数,返回它们之间所做运算的结果

定义注册simple tag

@register.simple_tag(name="plus")

def plus(a, b, c):

return "{} + {} + {}".format(a, b, c)

 

使用自定义simple tag

{% load app01_demo %}

{% plus "1" "2" "abc" %}

 

  1. inclusion_tag:多用于返回html代码片段;后续项目会使用

# templatetags/my_inclusion.py

 

from django import template

register = template.Library()

 

@register.inclusion_tag('result.html')

def show_results(n):

    n = 1 if n < 1 else int(n)

    data = ["第{}项".format(i) for i in range(1, n+1)]

    return {"data": data}

 

templates/snippets/result.html

 

<ul>

  {% for choice in data %}

    <li>{{ choice }}</li>

  {% endfor %}

</ul>

 

templates/index.html

 

<!DOCTYPE html>

<html lang="en">

<head>

 <meta charset="UTF-8">

 <meta http-equiv="x-ua-compatible" content="IE=edge">

 <meta name="viewport" content="width=device-width, initial-scale=1">

 <title>inclusion_tag test</title>

</head>

<body>

{% load inclusion_tag_test %}

{% show_results 10 %}

</body>

</html>

 

  1. urls.py(路由系统)

http://www.cnblogs.com/liwenzhou/p/8271147.html

    a. URLconf配置

    # 基本格式:

    from django.conf.urls import url

 

    urlpatterns = [

    url(正则表达式, views视图函数,参数,别名),

    ]

 

     # 在Django2.0 中用path替换了url(from django.urls import path)

 

    b. 正则表达式详解

       1)urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。

       2)若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。

       3)不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是^/articles。

          # Django settings.py配置文件中默认没有APPEND_SLASH 这个参数,但 Django 默认这个参数为APPEND_SLASH = True。 其作用就是自动在网址结尾加'/'。可设置APPEND_SLASH = False,改变默认值。

       4)每个正则表达式前面的'r' 是可选的但是建议加上。

 

    c. 正则匹配的模式

        1) 分组匹配      --> 调用视图函数的时候额外传递位置参数;正则表达式分组匹配(通过圆括号)来捕获URL中的值并以位置参数形式自动传递给视图的args。

           # *args, agrs = (a,b)

           url(r'^articles/([0-9]{4})/$', views.year_archive),

 

        2) 分组命名匹配   --> 调用视图函数的时候额外传递关键字参数

           url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),

 

        注意:

           a) 要么全都用分组匹配,要么全都用分组命名匹配,不要混着用!

           b) Django utl正则表达式匹配的位置:从第一个斜线到问号之前这一段的路径

           c) URL正则表达式捕获的值都是字符串类型,如果要参与后续运算,应先进行类型转换。

           d) 可以给视图函数的参数设置默认值

# 正则匹配时,不论是否分组\带参数,即都可以调用views中的page方法

               # urls.py中

               from django.conf.urls import url

               from . import views

 

               urlpatterns = [

                   url(r'^blog/$', views.page),

                   url(r'^blog/page(?P<num>[0-9]+)/$', views.page),

               ]

 

               # views.py中,可以为num指定默认值

               def page(request, num="1"):

                   pass

 

    d. include 分级路由(级级匹配:/app01/upload; 在第一级匹配app01,在第二级匹配upload)

       # 推荐在各个app下建立自己的urls.py

       查找的顺序:请求--> project/urls.py  --> app/urls.py  --> app/views.py

 

       from django.conf.urls import include, url

 

       urlpatterns = [

          url(r'^admin/', admin.site.urls),

          url(r'^blog/', include('blog.urls')),  # 可以包含其他的URLconfs文件

       ]

 

    e. 传递额外的参数给视图函数

       from django.conf.urls import url

       from . import views

 

       urlpatterns = [

          url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),

       ]

 

    f. URL匹配规则的别名(命名URL和URL反向解析(别名->正则表达式(URL)))

        1) 起别名是为了,增加代码的健壮性,不将URL硬编码到代码中!

 

        2) 用法

            a) 在views.py中如何根据别名找到url

                from django.urls import reverse

                url = reverse('别名')

 

            b) 在模板语言中如何根据别名找到url

                {% url '别名' %}

 

        3) 带参数的url如何反向生成?

            a) 位置参数

                i) 在views.py中:

                    reverse("别名", args=(参数1, 参数2, ...))

 

                ii) 在模板语言中:

                    {% url "别名" 参数1, 参数2... %}

 

            b). 关键字参数

                i) 在views.py中:

                    reverse("别名", kwargs={"k1":参数1, ...})

 

                ii) 在模板语言中:

                    {% url "别名" 参数1, 参数2... %}

                    # 在模版语言中,无法传递关键字参数,只能根据位置,依次传参

 

        4) namespace(命名空间), 是include的一个参数

           # 使用include语法,将其他的urls.py 包含进来

            from django.conf.urls import url, include

 

            urlpatterns = [

               url(r'^app01/', include('app01.urls', namespace='app01')),

               url(r'^app02/', include('app02.urls', namespace='app02')),

            ]

 

            语法:'命名空间名称:URL名称'

 

            # 这样两个app中url名称重复了,反转URL的时候就可以通过命名空间的名称得到当前的URL;即使app中URL的命名相同,也可以反转得到正确的URL了。

            模板中使用:

            {% url 'app01:detail' pk=12 pp=99 %}

 

            views中的函数中使用

            v = reverse('app01:detail', kwargs={'pk':11})

 

四、今日作业

用一个函数一个URL匹配模式实现 书书籍表、作者表、出版社表的展示和删除操作

关键点:

  1. URL匹配模式的设计(分组匹配或分组命名匹配;给URL匹配模式起别名)

2. 反射:由一个字符串,找到对应的类变量

3. URL的反向解析(别名--> 完整的URL)

4. 正则表达式

import re

# 写一个正则表达式, 只能从add delete edit list  这四个单次里面选一个

s1 = "delete"  # 匹配成功

s2 = "cut"  # 匹配不成功

 

r = re.compile(r'add|delete|edit|list')

print(r.match(s1))

print(r.match(s2))

 

# urls.py

url(r'(?P<operation>list|delete)_(?P<table_name>[a-zA-Z]+)/', views.op, name = 'list_delete'),

 

# views.py

def op(request,operation,table_name):

    table = table_name.capitalize()

    if hasattr(models,table):

        class_obj = getattr(models,table)

        if operation.upper() == 'LIST':

            ret = class_obj.objects.all()

            return render(request,'{}_{}.html'.format(table_name,operation),{'ret':ret})

        elif operation.upper() == 'DELETE':

            id = request.GET.get('id')

           class_obj.objects.get(id=id).delete()

            url = reverse('list_delete', kwargs={'operation':'list','table_name':table_name})

            return redirect(url)

posted @ 2018-06-19 21:07  yangli0504  阅读(118)  评论(0编辑  收藏  举报