模板

变量输出

  1. {{ name }} # 输出变量
  2. {{ users.0 }} # 去list第一个元素
  3. {{ user_dict.k1 }} # 取dict中元素

条件/循环

  1. {% if n == 1 %}
  2. {% elif n==2 %}
  3. {% else %}
  4. {% endif %}
  5. <ul>
  6. {% for item in users %}
  7. <li>{{ item }}</li>
  8. {% endfor %}
  9. </ul>
  • forloop.counter 当前循环计数,从1开始
  • forloop.counter0 当前循环计数,从0开始,标准索引方式
  • forloop.revcounter 当前循环的倒数计数,从列表长度开始
  • forloop.revcounter0 当前循环的倒数计数,从列表长度减1开始
  • forloop.first bool值,判断是不是循环的第一个元素
  • forloop.last bool值,判断是不是循环的最后一个元素
  • forloop.parentloop 用在嵌套循环中,得到parent循环的引用,然后可以使用以上的参数

函数

  1. {% for i in dic.keys %} # => dic.keys()
  2. # 模板中默认执行函数无需加括号,且不能传参数
  3. {% endfor %}

自定义函数

  • simple_filter
  • simple_tag
  1. 1. app中创建templatetags模块
  2. 2. 创建一个xxx.py文件
  3. 3. xxx.py
  4. ------------------------------
  5. from django import template
  6. register = template.Library() # register 名称不能变
  7. # simple_filter 只支持最多2个参数
  8. 可以作为条件语句反倒 if后面
  9. @register.filter
  10. def my_upper(value):
  11. return value.upper()
  12. def my_add(num1, num2):
  13. return num1+num2
  14. # simple_tag 支持多个参数
  15. 无法作为条件语句反倒 if后面
  16. @register.simple_tag
  17. def my_lower(value):
  18. return value.lower
  19. @register.simple_tag
  20. def my_join(s1,s2,s3):
  21. return s1+s2+s3
  22. @register.inclusion_tag("mb/show.html")
  23. def func(arg):
  24. # 这个数据将创给mb/show.html模板中渲染,渲染后将这个页面内容返回
  25. return {'name': 'hehe'}
  26. 4. 使用 xxx.html
  27. -----------------------------------
  28. {% load xxx %} # 导入模块 xxx.py
  29. # simple_filter
  30. {{ name | my_upper }}
  31. {{ n1 | my_add:"11" }} #冒号后面不能有空格
  32. # simple_tag
  33. {% my_lower "HEHE" %}
  34. {% my_join "a" "nihao" "hehe" %}

母版

  1. layout.html 母版文件
  2. ---------------------
  3. <html>
  4. ....
  5. {% block xx %}
  6. {% endblock %}
  7. ...
  8. </html>
  9. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  10. xxx.html 继承母版的html
  11. --------------------------------
  12. {% extends 'layout.html' %}
  13. {% block xx %}
  14. 这里的内容会在模板的block名为xxblock中显示
  15. {% endblock %}

include

  1. # 公共组件
  2. pub.html
  3. --------------------
  4. <h1>这是一个组件</h1>
  5. <div>
  6. {{ name }} # index导入后,变量可以在组件中直接显示
  7. <div>
  8. # 哪里需要组件代码 则直接 include
  9. index.html
  10. -----------------------------
  11. {% include "pub.html" %}

xss 脚本注入

Django对标签内容会自动转义,使用safe 取消转义, 使用safe要对特殊字符处理

  1. 模板中
  2. {{ content | safe }}
  3. views
  4. from django.utils.safestring import mark_safe
  5. temp = "<a href='https://www.baidu.com'>百度</a>"
  6. newtemp = mark_safe(temp) 模板中不加safe 也会以标签输出

模板中直接显示model中的choice中的中文

get_字段名_display()
使用values 和 values_list 获取数据时无效,只能是models对象

  1. # modles.py
  2. status_choice = (
  3. (1, '正常'),
  4. (2, '禁用'),
  5. )
  6. status = models.SmallIntegerFields(choices=status_choice)
  1. {{ item.get_status_display }}
  2. status = 1 显示 正常
  3. 函数 get_字段名_display

CSRF(XSRF)跨站伪造请求

  1. settings.py
  2. MIDDLEWARE = [
  3. # ...,
  4. # 注释下面 则关闭CSRF功能,整个网站都不验证
  5. django.middleware.csrf.CsrfViewMiddleware,
  6. # ...,
  7. ]
  8. '''
  9. xxx.html
  10. --------------------------
  11. '''
  12. <form >
  13. {% csrf_token %} #
  14. # 没有加csrf_token 会403错误
  15. # 自动生成 input 并在 cookies中也添加key为csrftoken
  16. <input type='hidden' name='csrfmiddlewaretoken' value='....' />
  17. {{ csrf_token }} # 只是csrf_token随机字符串
  18. </form>
  19. views.py
  20. ------------------------
  21. from django.views.decorators.csrf import csrf_exempt, csrf_protect
  22. # 全局使用时, csrf_exempt 局部禁用
  23. # 全局禁用时, csrf_protect 局部启用
  24. # 只对下列不进行验证, 添加装饰器
  25. @csrf_exempt
  26. def test(request):
  27. ...
  28. CBV
  29. --------------------------
  30. from django.utils.decorators import method_decorator
  31. @method_decorator(csrf_protect) # 只能加在类上,不能加在方法上
  32. class Foo(View):
  33. def get(self, request):
  34. ...
  35. def post(self, request):
  36. ...

ajax请求时CSRF

  1. 1. 通过获取inputcsrf_token(可用 {{csrf_token}}),在data中添加 csrfmiddlewaretoken
  2. $.ajax({
  3. url: '{% url 'user_reset' form.instance.pk %}',
  4. type: 'POST',
  5. datatype: 'json',
  6. data: {'csrfmiddlewaretoken': '{{ csrf_token }}'},
  7. success: function (res) {
  8. alert(res.msg)
  9. },
  10. error: function (err) {
  11. console.log(err);
  12. alert('网络或服务器问题,重置密码失败')
  13. }
  14. })
  15. 2. 通过cookie获取,请请求头中
  16. var csrf_token = $.cookie('csrftoken'); # jquery cookie 模块
  17. $.ajax({
  18. url: 'xxxx',
  19. type: 'post',
  20. headers:{
  21. 'X-CSRFToken': csrf_token,
  22. }
  23. data:{}
  24. ...
  25. })

CBV

  1. urls.py
  2. ---------------------------
  3. # 不同的请求方式,会执行Login类中不同的方法
  4. url(r'^login.html$', views.Login.as_view())
  5. views.py
  6. ---------------------------
  7. from django.views import View
  8. class Login(View):
  9. # get 查 post 创建 put 更新 delete 删除
  10. def get(self, request):
  11. # /login.html get的请求执行该方法
  12. ...
  13. def post(self, request):
  14. # /login.html post的请求执行该方法
  15. ...
  16. ...

CBV中dispatch方法

CBV中优先执行的是dispatch方法

  1. class Login(View):
  2. def dispatch(self, request, *args, **kwargs):
  3. # 重写dispatch方法,可在该方法中对get、post等进行批量操作
  4. # ...
  5. # 调用父类的方法
  6. obj = super(Login, self).dispatch(request, **args, **kwargs)
  7. return obj
  8. def get(self, request):
  9. # /login.html get的请求执行该方法
  10. # ...
  11. def post(self, request):
  12. # /login.html post的请求执行该方法
  13. # ...
  14. # ...

CBV应用装饰器

@method_decorator(装饰器名, name=’get/post/…’)

  1. # 1. 在类上加 name可省略,加上后制定方法名,则对改方法生效
  2. @method_decorator(装饰器名, name='get/post/...')
  3. class Foo(View):
  4. def get(slef, request):
  5. ...
  6. def post(self, request):
  7. ...
  8. ...
  9. # 2. 直接在方法上加
  10. class Foo(View):
  11. @method_decorator(装饰器名) # 只对改方法生效
  12. def get(slef, request):
  13. ...
  14. def post(self, request):
  15. ...
  16. ...
  • csrf_exempt的装饰器时,应加dispatch方法上
  • 或加在类上 @method_decorator(csrf_exempt, name='dispatch')

FBV

  1. urls.py
  2. ---------------------------
  3. url(r'^login.html$', views.login)
  4. views.py
  5. -----------------------------
  6. def login(request):
  7. ...