博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
simple_tag,filte,分页以及cookie和装饰器
阅读量:5877 次
发布时间:2019-06-19

本文共 8977 字,大约阅读时间需要 29 分钟。

自定义simple_tag

内置的方法

首先Django中包含了很多内置的方法:

这里通过lower实现

在views视图函数中写如下代码:

def tp3(request):    name= "ABCDEFG"    return  render(request,"tp3.html",{
"name":name})

在urls路由关系中添加如下:

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

在tp3页面中写如下:

    {

{ name }}

    {

{ name|lower }}

最后效果如下:

自定义方法

使用simple_tag的方法:

1、    在app下创建templatetags目录

2、    创建py文件

3、    创建template对象register

4、    @register.simple_tag

def func()

如果函数有参数:

def func(a1,a2)

5、    在settings配置文件注册app

6、    在页面文件顶部{%load py文件%},如果存在继承,这个要放在继承下面

7、    最后在页面使用的时候{% func %},如果有参数

{%func 2 3 %}

这里有几个问题需要注意:

1、    在app下创建templatetags目录必须为templatetags不能更改

2、    创建py文件的时候名字可以随便定义

3、    在py文件中必须写如下代码:

 

from django import templatefrom django.utils.safestring import mark_saferegister = template.Library()@register.simple_tag

这四行代码必须有,并且的template对象register名字不能更改

按照上面的规则,在app下创建templatetags目录

然后创建一个test.py文件,代码如下:

#AUTHOR:FANfrom django import templatefrom django.utils.safestring import mark_saferegister = template.Library()@register.simple_tagdef func():    return 123

并在setting中添加:

tp3.html中代码如下(注意高亮部分):

{% load test %}    
Title {
{ name }} {
{ name|lower }} {% func %}

最后效果如下:

我们将test中的func改成传递参数的,如下所示:

def func(a1,a2):

    return a1+a2

在tp3.html中传递参数:

  {% func 5 3 %}

结果如下:

自定义filter

filter和simple_tag的方法基本一样,只需要做如下修改:

将test.py文件中@register.simple_tag替换为@register.filter

在页面中代码改为:

{

{ "zhaofan" |func:"赵凡" }}

这样最终在页面的效果如下:

 

 

而这里对比filter和simple_tag,我们可以发现各有优缺点

1、其中fileter可以放在模板语言中的if条件中,而simple_tag则不能如:

    {% if "zhaofan" |func:"赵凡" %}

       

    {% endif %}

2、filter参数固定,simple_tag参数任意

分页

在前端防止因为xss而现实字符串的可以通{

{ page_str|save}}

后端:可以通过导入from django.utils.safestring import mark_safe,然后page_str = mark_safe(page_str)

通过下面例子用于理解分页

这里将分页的功能封装了一个类,改类内容如下:

#AUTHOR:FANfrom django.utils.safestring import mark_safeclass Page:    def __init__(self,current_page,data_count,per_page_count=10,page_num = 7):        '''        :param current_page: 当前页        :param data_count: 数据的总数目        :param per_page_count: 每页显示的数目        :param page_num: 显示几页内容        '''        self.current_page = current_page        self.data_count = data_count        self.per_page_count=per_page_count        self.page_num = page_num    @property    def start(self):        '''        :return: 返回得到起始        '''        return (self.current_page-1)*self.per_page_count    @property    def end(self):        '''        :return: 返回结束        '''        return self.current_page*self.per_page_count    @property    def total_count(self):        '''        :return: 返回总页数        '''        v, y = divmod(self.data_count, self.per_page_count)        if y:            v += 1        return v    def page_str(self,base_url):        '''        :param base_url: 这里是用于自定义url前缀        :return: 返回的为页面下端要显示的跳转页的html语言的字符串        '''        page_list = []        if self.total_count < self.page_num:            start_index = 1            end_index = self.total_count + 1        else:            if self.current_page <= (self.page_num + 1) / 2:                start_index = 1                end_index = self.page_num + 1            else:                start_index = self.current_page - (self.page_num - 1) / 2                end_index = self.current_page + (self.page_num + 1) / 2                if self.current_page + (self.page_num + 1) / 2 > self.total_count:                    end_index = self.total_count + 1                    start_index = self.total_count - self.page_num + 1        if self.current_page == 1:            prev = '上一页'        else:            prev = '上一页' % (base_url,self.current_page - 1)        page_list.append(prev)        for i in range(int(start_index), int(end_index)):            if i == self.current_page:                temp = '%s' % (base_url,i, i)            else:                temp = '%s' % (base_url,i, i)            page_list.append(temp)        if self.current_page == self.total_count:            nex = '下一页'        else:            nex = '下一页' % (base_url,self.current_page + 1)        page_list.append(nex)        go_page = """        跳转                """ %(base_url)        page_list.append(go_page)        page_str = "".join(page_list)        page_str = mark_safe(page_str)        return page_str

在views函数中调用:

from utils import paginationdef user_list(request):    current_page = request.GET.get("p",1)    current_page = int(current_page)    page_obj = pagination.Page(current_page,len(LI))    data = LI[page_obj.start:page_obj.end]    page_str = page_obj.page_str("/user_list/")    return render(request,"user_list.html",{
"data":data,"page_str":page_str})

最终的效果如下:

cookie

客户端浏览器上的一个文件

以字典的方式存在

通常很多网站登录之后,网站的右上角会显示当前用户的用户名,实现例子如下:

views里写如下代码:

def login(request):    print(request.method)    if request.method=="GET":        return render(request,"login.html")    if request.method =="POST":        u = request.POST.get("username")        p = request.POST.get("pwd")        dic = user_info.get(u)        print(u,p)        if not dic:            return render(request,"login.html")        if dic["pwd"] == p:            res = redirect("/index")            res.set_cookie('username1',u)            return res        else:            return render(request, "login.html")def index(request):    #获取当前登录的用户名    v = request.COOKIES.get("username1")    if not v:        return redirect("/login")    return render(request,"index.html",{
"current_user":v})

这样用户如果没有登录的情况下就不能直接访问index页面了

,并且如果用户登录之后也能显示当前用户的用户名,也就是实现了用户认证

设置Cookie:

res.set_cookie(key,value)

参数:

key              键

value=‘’       值

max_age=None      超时时间,以秒作为单位。默认是关闭浏览器失效

expires=None      超时时间,这个是可以设置datatime

path="/"          Cookie生效的路径

domain=None      Cookie生效的域名

secure=False      https传输

httponly=False    只能http协议传输,无法被JavaScript获取

分页改造(结合cookie)

user_list.html代码如下:

    
Title
    {% for item in data %} {% include 'li.html' %} {% endfor %}

页面效果如上,实现的功能是当通过下拉框选择不同的选项时,即每页显示的数量,这里利用了jquery的cookie,jquery.cookie.js

关于cookie的加密

前文中我们通过

res.set_cookie('username1',u)

设置cookie,其实还有一种加密的方式,即:

res.set_signed_cookie("username1",u,salt="jiami")

通过salt这个参数实现加密,同样的获取cookie的时候也需要加上salt参数才能进行解密

用户认证装饰器

FBV的装饰器用法

我们前面代码中:

def index(request):    #获取当前登录的用户名    v = request.COOKIES.get("username1")    if not v:        return redirect("/login")    return render(request,"index.html",{
"current_user":v})

如果我们有多页面都需要判断用户是否登录,如果每个都这样写就需要写很多遍,所以这里我们可以通过装饰器实现

将上述代码进行更改:

def auth(func):    def inner(request,*args,**kwargs):        v = request.COOKIES.get("username1")        if not v:            return redirect("/login")        return func(request,*args,**kwargs)    return inner@authdef index(request):    #获取当前登录的用户名    v = request.COOKIES.get("username1")    return render(request,"index.html",{
"current_user":v})

CBV的装饰器用法

下面是一个普通的CBV用法例子:

from django import viewsclass Order(views.View):    def get(self,request):        v = request.COOKIES.get("username1")        if not v:            return redirect("/login")        return render(request, "index.html", {
"current_user": v}) def post(self,request): v = request.COOKIES.get("username1") return render(request, "index.html", {
"current_user": v})

如果我们只对get请求做认证

def auth(func):    def inner(request,*args,**kwargs):        v = request.COOKIES.get("username1")        if not v:            return redirect("/login")        return func(request,*args,**kwargs)    return innerfrom django import viewsfrom django.utils.decorators import method_decoratorclass Order(views.View):    @method_decorator(auth)    def get(self,request):        v = request.COOKIES.get("username1")        return render(request, "index.html", {
"current_user": v}) def post(self,request): v = request.COOKIES.get("username1") return render(request, "index.html", {
"current_user": v})

这样当访问order的时候就加上了验证功能

但是这样是只给get方法加验证,如果想要给更多得方法加验证的时候,通过下面方法实现:

 

def auth(func):    def inner(request,*args,**kwargs):        v = request.COOKIES.get("username1")        if not v:            return redirect("/login")        return func(request,*args,**kwargs)    return innerfrom django import viewsfrom django.utils.decorators import method_decoratorclass Order(views.View):    @method_decorator(auth)    def dispatch(self, request, *args, **kwargs):        return super(Order,self).dispatch(request, *args, **kwargs)    def get(self,request):        v = request.COOKIES.get("username1")        return render(request, "index.html", {
"current_user": v}) def post(self,request): v = request.COOKIES.get("username1") return render(request, "index.html", {
"current_user": v})

因为CBV每次需要先执行一个dispatch方法,我们在dispatch方法上加认证,这样就相当于在所有的上面加上了认证

但是这种方法有人会觉得多写了一个dispatch方法,可以将其简化为:

@method_decorator(auth,name="dispatch")class Order(views.View):    def get(self,request):        v = request.COOKIES.get("username1")        return render(request, "index.html", {
"current_user": v}) def post(self,request): v = request.COOKIES.get("username1") return render(request, "index.html", {
"current_user": v})

 

所有的努力都值得期许,每一份梦想都应该灌溉!

转载地址:http://prkix.baihongyu.com/

你可能感兴趣的文章
Ubuntu ctrl+alt会导致窗口还原的问题
查看>>
第四十期百度技术沙龙笔记整理
查看>>
推荐系统那点事 —— 基于Spark MLlib的特征选择
查看>>
linux 下RTL8723/RTL8188调试记录(命令行)【转】
查看>>
開始新的征程
查看>>
SpringMVC案例1——对User表进行CRUD操作
查看>>
看雪CTF第十四题
查看>>
模拟生命_吸烟致癌?
查看>>
[Contiki系列论文之1]Contiki——为微传感器网络而生的轻量级的、灵活的操作系统...
查看>>
Android 网络编程 记录
查看>>
微软同步发行Windows 10和Windows 10 Mobile系统更新
查看>>
Maven 传递依赖冲突解决(了解)
查看>>
Zeppelin的入门使用系列之使用Zeppelin运行shell命令(二)
查看>>
[Spark][Python]Spark Join 小例子
查看>>
form表单下的button按钮会自动提交表单的问题
查看>>
大战设计模式【11】—— 模板方法模式
查看>>
springBoot介绍
查看>>
Intellij IDEA 快捷键整理
查看>>
Redis 通用操作2
查看>>
11. Spring Boot JPA 连接数据库
查看>>