s10_part3_django_html模板_view_model

s10_part3_django_html模板_view_model_

模板系统

reference:https://www.cnblogs.com/liwenzhou/p/7931828.html
from part4_d66

1. 模板系统(字符串替换)
		1. 语法
			1. 变量相关: {{ name }},{{name|length}},{{name|default:"默认值"}}
			2. 逻辑相关:
				1. if判断
					{% if a > b %}
					{% endif %}

					{% if a > b %}
					{% else %}
					{% endif %}

					{% if a > b %}
					{% elif %}
					{% else %}
					{% endif %}
				2. for循环
					1. for循环的基本用法:
						{% for i in name_list %}
							{{ i }}
						{% endfor %}

						{% for i in name_list %}
							{{ i }}
						{% empty %}
							空空如也
						{% endfor %}

					2. for循环可用的属性:
						forloop.counter
						forloop.counter0
						forloop.revcounter
						forloop.revcounter0

						forloop.first
						forloop.last

						forloop.parentloop  --> 两层for循环,内层循环引用外层循环

		2. filter
			1. 常用的内置filter
				1. length
				2. filesizeformat       --> 格式化文件大小的
				3. date:'Y-m-d H:i:s'   --> 格式化时间的
				4. slice
				5. safe                 --> XSS攻击(跨站脚本攻击)
				6. truncatechars:20     --> 截取字符,超过的用...表示
				7. default

			2. 自定义的filter
				示例:
					1. addsb
					2. addstr
				具体的实现方式:
					1. 定义阶段
						1. 在app下面新建一个python的包:templatetags
						2. 在上面的Python包中新建一个Python文件,名字随意
						3. 在上述python文件中:
							from django import template

							# 生成一个注册用的实例
							register = template.Library()
							# 定义并注册一个自定义的filter函数
							@register.filter(name='addsb')
							def add_sb(arg):
								return "{} sb".format(arg)
					2. 调用阶段:
						1. 在Django的模板文件中,导入刚才新建的python文件
							{% load py文件名 %}
						2. 按照filter的语法调用
							{{ name|addsb }}


返回顶部

from part4_d67

1. 模板语言(字符串替换)
		1. 母版和继承
			1. 母版使用场景
				html页面有重复的代码,把它们提取出来放到一个单独的html文件。
				(比如:导航条和左侧菜单)
			2. 子页面如何使用母版?
				{% extends 'base.html' %}   --> 必须要放在子页面的第一行

				母版里面定义block(块),子页面使用block(块)去替换母版中同名的块

        通过在母板中使用{% block  xxx %}来定义"块"。

        在子页面中通过定义母板中的block名来对应替换母板中相应的内容。

        {% block page-main %}
          <p>世情薄</p>
          <p>人情恶</p>
          <p>雨送黄昏花易落</p>
        {% endblock %}


		2. 组件
			1. 什么时候用组件?
				重复的代码,包装成一个独立的小html文件。
			2. 如何使用?
				{% include 'nav.html' %}

		3. Django模板语言中关于静态文件路径的灵活写法
			1. 利用Django模板语言内置的static方法帮我拼接静态文件的路径
				{% load static %}
				<link href="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
			2. 利用内置的get_static_prefix获取静态文件路径的别名,我们自行拼接路径
				{% load static %}
				<link href="{% get_static_prefix %}bootstrap/css/bootstrap.min.css" rel=stylesheet>
			3. as语法(一个路径多次用到,可以使用as保存到一个变量,后面就直接使用变量代替具体路径)
		4. 自定义的simple_tag
			比filter高级一点点
			它可以接受的参数个数大于2

		5. 自定义的inclusion_tag
			用来返回一段html代码(示例:返回ul标签)

			1. 定义阶段
				在app下面新建templatetags 文件夹(注意是Python包)
				新建一个py文件

				from django import template
				# 生成注册示例,名字必须是register
				register = template.Library()
				@register.inclusion_tag("ul.html")
				def show_ul(num):
					num = 1 if num < 1 else int(num)
					data = ["第{:0>3}号技师".format(i) for i in range(1, num+1)]
					return {"data": data}

			2. 调用阶段
				{% load xx %}
				{% show_ul 10 %}

返回顶部

视图

reference:https://www.cnblogs.com/liwenzhou/p/8305104.html
from part4_d67

1. CBV(class base view)和FBV(function base view)

		2. request对象
				1. request.method    --> 获取请求的方法(GET、POST等)
        request.post -->得到字典类型
        request.body -> 得到字符串类型
				request.path_info   --> 获取用户请求的路径(不包含IP和端口和URL参数)


		3. response
			基础必备三件套(求学要严谨)
			1. HttpResponse        --> 返回字符串内容
			2. render              --> 返回一个html页面             
			3. redirect            --> 返回一个重定向(告诉浏览器再去访问另外的网址)
			4. JsonResponse

CBV和FBV

FBV

# FBV版添加班级
def add_class(request):
    if request.method == "POST":
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")
    return render(request, "add_class.html")

CBV

# CBV版添加班级
from django.views import View

class AddClass(View):

    def get(self, request):
        return render(request, "add_class.html")

    def post(self, request):
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")

注意:

使用CBV时,urls.py中也做对应的修改:

# urls.py中
url(r'^add_class/$', views.AddClass.as_view()),

返回顶部

给视图加装饰器

BV本身就是一个函数,所以和给普通的函数加装饰器无差:

def wrapper(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        ret = func(*args, **kwargs)
        end_time = time.time()
        print("used:", end_time-start_time)
        return ret
    return inner


# FBV版添加班级
@wrapper
def add_class(request):
    if request.method == "POST":
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")
    return render(request, "add_class.html")

类中的方法与独立函数不完全相同,因此不能直接将函数装饰器应用于类中的方法 ,我们需要先将其转换为方法装饰器。

Django中提供了method_decorator装饰器用于将函数装饰器转换为方法装饰器。

# CBV版添加班级
from django.views import View
from django.utils.decorators import method_decorator

class AddClass(View):

    @method_decorator(wrapper)
    def get(self, request):
        return render(request, "add_class.html")

    def post(self, request):
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")

关于CBV的扩展阅读

# 使用CBV时要注意,请求过来后会先执行dispatch()这个方法,如果需要批量对具体的请求处理方法,如get,post等做一些操作的时候,这里我们可以手动改写dispatch方法,这个dispatch方法就和在FBV上加装饰器的效果一样。

class Login(View):

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

    def get(self,request):
        return render(request,'login.html')

    def post(self,request):
        print(request.POST.get('user'))
        return HttpResponse('Login.post')

返回顶部

路由系统

reference:https://www.cnblogs.com/liwenzhou/p/8271147.html
from part4_d67
Django 1.11版本 URLConf官方文档:
https://docs.djangoproject.com/en/1.11/topics/http/urls/

基本格式:

from django.conf.urls import url

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

Django 2.0版本中的路由系统已经替换成下面的写法

from django.urls import path

urlpatterns = [
    path('articles/2003/', views.special_case_2003),
    path('articles/<int:year>/', views.year_archive),
    path('articles/<int:year>/<int:month>/', views.month_archive),
    path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]

官方文档:
https://docs.djangoproject.com/en/2.0/topics/http/urls/

参数说明:

正则表达式:一个正则表达式字符串
views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
参数:可选的要传递给视图函数的默认参数(字典形式)
别名:一个可选的name参数

分组命名匹配

分组命名正则表达式组的语法是(?P<name>pattern),其中name是组的名称,pattern是要匹配的模式。

捕获的参数永远都是字符串
每个在URLconf中捕获的参数都作为一个普通的Python字符串传递给视图,无论正则表达式使用的是什么匹配方式。例如,下面这行URLconf 中:

url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
#传递到视图函数views.year_archive() 中的year 参数永远是一个字符串类型

include其他的URLconfs

#At any point, your urlpatterns can “include” other URLconf modules. This
#essentially “roots” a set of URLs below other ones.

#For example, here’s an excerpt of the URLconf for the Django website itself.
#It includes a number of other URLconfs:


from django.conf.urls import include, url

urlpatterns = [
   url(r'^admin/', admin.site.urls),
   url(r'^blog/', include('blog.urls')),  # 可以包含其他的URLconfs文件
]

返回顶部

命名URL和URL反向解析

例子一:

url(r'^index999', views.home, name='home'),  # 给我的url匹配模式起名为 home
url(r'^index/(\d*)', views.index, name='index'),  # 给我的url匹配模式起名为index,带参数的

在模板里面可以这样引用:以后就不需要写死URL代码了,只需要通过名字来调用当前的URL

{% url 'home' %}

在views函数中可以这样引用:

from django.urls import reverse

reverse("index", args=("2018", ))

例子二:

from django.conf.urls import url

from . import views

urlpatterns = [
    # ...
    url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
    # ...
]

模板中的引用:

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>

<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>

python代码中的引用


from django.urls import reverse
from django.shortcuts import redirect

def redirect_to_year(request):
    # ...
    year = 2006
    # ...
    return redirect(reverse('news-year-archive', args=(year,)))

返回顶部

命名空间模式

即使不同的APP使用相同的URL名称,URL的命名空间模式也可以让你唯一反转命名的URL。

from django.conf.urls import url, include

urlpatterns = [
    url(r'^app01/', include('app01.urls', namespace='app01')),
    url(r'^app02/', include('app02.urls', namespace='app02')),
]

app01中的urls.py

from django.conf.urls import url
from app01 import views

app_name = 'app01'
urlpatterns = [
    url(r'^(?P<pk>\d+)/$', views.detail, name='detail')
]

app02中的urls.py

from django.conf.urls import url
from app02 import views

app_name = 'app02'
urlpatterns = [
    url(r'^(?P<pk>\d+)/$', views.detail, name='detail')
]

语法:

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

模板中使用:

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

views中的函数中使用

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

返回顶部

posted @ 2018-11-19 14:28  rootid  阅读(187)  评论(0编辑  收藏  举报