Django之视图函数

视图

request

​ HttpRequest对象就是视图函数的参数request

print(request)  
#<WSGIRequest: GET '/home/'>
# print(dir(request))

print(request.path) 
#/home/  纯路径

print(request.path_info) 
#/home/  纯路径

print(request.get_full_path()) 
#/home/?a=1&b=2  全路径(不包含ip地址和端口)

print(request.META)  
#请求头相关数据,是一个字典

print(request.method)  
# GET

print(request.GET)

print(request.POST)

print(request.body)  
# 能够拿到请求数据部分的数据(post,get没有)

HttpResponse对象

HTTPResponse('字符串')
render(request,'xx.html')
redirect 重定向
# from django.shortcuts import redirect-
# 用法  redirect(路径) 示例:redirect('/index/')

CBV和FBV

FBV(function base views)

	就是在视图里使用函数处理请求。
from django.http import HttpResponse
def my_view(request):
     if request.method == 'GET':
            return HttpResponse('OK')

CBV(class base views)

​ 就是在视图里使用类处理请求。

from django.http import HttpResponse
from django.views import View
class MyView(View):
      def get(self, request):
            return HttpResponse('OK')

作用

  Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在加入了Class-Based-View。可以用类写View。

​ 这样做的优点主要下面两种:

​ 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)

​ 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性

CBV调用流程

​ Django的url是将一个请求分配给可调用的函数的,而不是一个class。针对这个问题,class-based view提供了一个as_view()静态方法(也就是类方法),调用这个方法,会创建一个类的实例,然后通过实例调用dispatch()方法,dispatch()方法会根据request的method的不同调用相应的方法来处理request(如get() , post()等)。到这里,这些方法和function-based view差不多了,要接收request,得到一个response返回。如果方法没有定义,会抛出HttpResponseNotAllowed异常。

urls.py的写法
from django.conf.urls import url
from myapp.views import MyView #引入我们在views.py里面创建的类
  
urlpatterns = [
     url(r'^index/$', MyView.as_view()),
]
类写法
class Myd(View):
    name = 'sb'

    def get(self,request,n):
        print('get方法执行了')
        print('>>>',n)
        return render(request,'cvpost.html',{'name':self.name})

    def post(self,request,n):
        print('post方法被执行了')
        return HttpResponse('post')

视图加装饰器

装饰FBV

def wrapper(func):
        def inner(*args, **kwargs):
            print(11111)
            ret = func(*args, **kwargs)
            print(22222)
            return ret
        return inner

@wrapper
def index(request):
    print('xxxxx')
	return HttpResponse('indexxxxxxxxx')

装饰CBV

def wrapper(func):
        def inner(*args, **kwargs):
            print(11111)
            ret = func(*args, **kwargs)
            print(22222)
            return ret
        return inner

方式1

from django.utils.decorator import method_decorator

class LoginView(View):
	@method_decorator(wrapper)  # 方式1
	def get(self,request):
		print('小小小小')
		return render(request,'login.html')

方式2

class LoginView(View):     
	# 方式2
	def dispatch(self, request, *args, **kwargs):
		print('xx请求来啦!!!!')
		ret = super().dispatch(request, *args, **kwargs)
		print('请求处理的逻辑已经结束啦!!!')
		return ret
    
    def get(self,request):
		print('小小小小')
		return render(request,'login.html')

方式3

@method_decorator(wrapper,name='get')  # 方式3
class LoginView(View):
	def get(self,request):
		print('小小小小')
		return render(request,'login.html')

模板渲染

{{ 变量 }}
{% 逻辑 %}

写法

view中:

def index(request):
    import datetime
    s = "hello"
    l = [111, 222, 333]  # 列表
    dic = {"name": "yuan", "age": 18}  # 字典
    date = datetime.date(1993, 5, 2)  # 日期对象

    class Person(object):
        def __init__(self, name):
            self.name = name
        def dream(self):
            return 'dreamer'
    person_yuan = Person("chao")  # 自定义类对象
    person_egon = Person("yantao")
    person_alex = Person("jinxin")

    person_list = [person_yuan, person_egon, person_alex]

    return render(request, "index.html", {"l": l, "dic": dic, "date": date, "person_list": person_list})
    # return render(request,'index.html',locals())
    # locals()获取函数内容所有的变量,然后通过render方法给了index.html文件进行模板渲染,如果你图省事,你可以用它,但是很多多余的变量也被传进去了,效率低

html文件中:

<h4>{{s}}</h4>
<h4>列表:{{ l.0 }}</h4>
<h4>列表:{{ l.2 }}</h4>
<h4>字典:{{ dic.name }}</h4>
<h4>日期:{{ date.year }}</h4>
<!--取列表的第1个对象的name属性的值-->

<h4>类对象列表:{{ person_list.0.name }}</h4>
<!--取列表的第1个对象的dream方法的返回值,如果没有返回值,拿到的是none-->

<h4>类对象列表:{{ person_list.0.dream }}</h4>
注意:
    调用对象里面的方法的时候,不需要写括号来执行,并且只能执行不需要传参数的方法,如果这个方法需要传参数,那么模板语言不支持,不能帮你渲染

过滤器

语法

{{ value|filter_name:参数 }}

注意事项

​ 过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。
​ 过滤器可以接受参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个词。
​ 过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:', ' }}
​ '|'左右没有空格没有空格没有空格

内置过滤器

{{ value|default:"nothing" }}
# 如果value没有传值或者值为空的话就显示nothing

{{ value|length }}
# 返回value的长度,如 value=['a', 'b', 'c', 'd']的话,就显示4.

{{ value|filesizeformat }}
# 如果 value 是 123456789,输出将会是 117.7 MB。

{{ value|slice:"2:-1" }}
# 切片

{{ value|date:"Y-m-d H:i:s" }}
# value = datetime.datetime.now()

{{ value|safe }}
# value = "<a href='#'>点我</a>", 告诉django这段代码安全, 不需转义

{{ value|truncatechars:9 }}
# value = "hello girl hi baby yue ma"  结果是"hello ..." 只显示9个字符(6个字符+3个省略号)

{{ value|truncatewords:3 }}
# value = "hello girl hi baby yue ma" 结果是 "hello girl h1..." 只显示3个词

{{ value|cut:' ' }}
# value = 'i love you',那么将输出'iloveyou'.

{{ list|join:', ' }}
# 字符串连接列表

标签

for循环标签

循环列表等
{% for person in person_list %}
    <p>{{ person.name }}</p>  <!--凡是变量都要用两个大括号括起来-->
{% endfor %}

循环字典
{% for key,val in dic.items %}
    <p>{{ key }}:{{ val }}</p>
{% endfor %}

empty
{% for person in person_list %}
    <p>{{ person.name }}</p>  <!--凡是变量都要用两个大括号括起来-->
{% empty %}
	<p>没有找到东西!</p>
{% endfor %}


forloop.counter            当前循环的索引值(从1开始),forloop是循环器,通过点来使用功能
forloop.counter0           当前循环的索引值(从0开始)
forloop.revcounter         当前循环的倒序索引值(从1开始)
forloop.revcounter0        当前循环的倒序索引值(从0开始)
forloop.first              当前循环是不是第一次循环(布尔值)
forloop.last               当前循环是不是最后一次循环(布尔值)
forloop.parentloop         本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等
示例:
	{% for i in d2 %}
        {% for k,v in d1.items %}

            <li>{{ forloop.counter }}-- {{ forloop.parentloop.counter }} === {{ k }} -- {{ v }}</li>

        {% endfor %}

    {% endfor %}

if判断标签

{% if num > 100 or num < 0 %}
    <p>无效</p>  <!--不满足条件,不会生成这个标签-->
{% elif num > 80 and num < 100 %}
    <p>优秀</p>
{% else %}  <!--也是在if标签结构里面的-->
    <p>凑活吧</p>
{% endif %}

if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断,注意条件两边都有空格。

with

方法1
{% with total=business.employees.count %}  #注意等号两边不能有空格
    {{ total }} <!--只能在with语句体内用-->
{% endwith %}
方法2
{% with business.employees.count as total %}
    {{ total }}
{% endwith %}
posted @ 2019-11-26 17:43  边城bei  阅读(149)  评论(0编辑  收藏  举报