1、自定义标签

2、图片验证码

3、生成邮箱验证码、发送邮件

4、评论树实现

5、组合搜索(Q)


1、自定义标签

配置:

a.在app中新建文件夹  templatetags,里面新建  xx.py文件(如tags.py)

b.tags.py文件中:

#自定义标签
from django import template register = template.Library() @register.simple_tag
def render_app_name(admin_class):
return admin_class.model._meta.verbose_name

ps:如果返回的对象有html标签,则需要用mark_safe()来包裹返回值,同时引入

from django.utils.safestring import mark_safe

c.settings文件中配置:

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
# 使用自定义标签是,应该加上这个配置,以便于找到tags的位置
'libraries':{
'tags': 'king_admin.templatetags.tags', }
},
},
]

d、.html文件中

开头处加载:

{% load tags %}
{#加载自定义标签#}  

中间处引入:

<tr>
<td>{% render_app_name admin %}</td>
#函数名称 参数
<td>add</td>
<td>change</td>
</tr>

e、给返回的数据起个别名,用as

<tr>
<td>{% render_app_name admin as obj %}</td>
#函数名称 参数 返回的数据的别名为obj </tr>

2、图片验证码

原理:自动生成验证码图片,同时将验证码放在session中,以便取用。

前端中,验证码图片的src指向该验证码函数,每访问一次就重新生成一次验证码图片和对应验证码

a、在utils文件夹中新建check_code.py,生成图片的代码,用于生成验证码和对应的图片

#生成验证码图片

import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter
# pip3 install Pillow
_letter_cases = "abcdefghjkmnpqrstuvwxy" # 小写字母,去除可能干扰的i,l,o,z
_upper_cases = _letter_cases.upper() # 大写字母
_numbers = ''.join(map(str, range(3, 10))) # 数字
init_chars = ''.join((_letter_cases, _upper_cases, _numbers)) def create_validate_code(size=(120, 30),
chars=init_chars,
img_type="GIF",
mode="RGB",
bg_color=(255, 255, 255),
fg_color=(0, 0, 255),
font_size=18,
font_type="Monaco.ttf",
length=4,
draw_lines=True,
n_line=(1, 2),
draw_points=True,
point_chance = 2):
'''
@todo: 生成验证码图片
@param size: 图片的大小,格式(宽,高),默认为(120, 30)
@param chars: 允许的字符集合,格式字符串
@param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG
@param mode: 图片模式,默认为RGB
@param bg_color: 背景颜色,默认为白色
@param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF
@param font_size: 验证码字体大小
@param font_type: 验证码字体,默认为 ae_AlArabiya.ttf
@param length: 验证码字符个数
@param draw_lines: 是否划干扰线
@param n_lines: 干扰线的条数范围,格式元组,默认为(1, 2),只有draw_lines为True时有效
@param draw_points: 是否画干扰点
@param point_chance: 干扰点出现的概率,大小范围[0, 100]
@return: [0]: PIL Image实例
@return: [1]: 验证码图片中的字符串
''' width, height = size # 宽, 高
img = Image.new(mode, size, bg_color) # 创建图形
draw = ImageDraw.Draw(img) # 创建画笔 def get_chars():
'''生成给定长度的字符串,返回列表格式'''
return random.sample(chars, length) def create_lines():
'''绘制干扰线'''
line_num = random.randint(*n_line) # 干扰线条数 for i in range(line_num):
# 起始点
begin = (random.randint(0, size[0]), random.randint(0, size[1]))
#结束点
end = (random.randint(0, size[0]), random.randint(0, size[1]))
draw.line([begin, end], fill=(0, 0, 0)) def create_points():
'''绘制干扰点'''
chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100] for w in range(width):
for h in range(height):
tmp = random.randint(0, 100)
if tmp > 100 - chance:
draw.point((w, h), fill=(0, 0, 0)) def create_strs():
'''绘制验证码字符'''
c_chars = get_chars()
strs = ' %s ' % ' '.join(c_chars) # 每个字符前后以空格隔开 font = ImageFont.truetype(font_type, font_size)
font_width, font_height = font.getsize(strs) draw.text(((width - font_width) / 3, (height - font_height) / 3),
strs, font=font, fill=fg_color) return ''.join(c_chars) if draw_lines:
create_lines()
if draw_points:
create_points()
strs = create_strs() # 图形扭曲参数
params = [1 - float(random.randint(1, 2)) / 100,
0,
0,
0,
1 - float(random.randint(1, 10)) / 100,
float(random.randint(1, 2)) / 500,
0.001,
float(random.randint(1, 2)) / 500
]
img = img.transform(size, Image.PERSPECTIVE, params) # 创建扭曲 img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强(阈值更大) return img, strs

 b、在views文件夹中建account.py用于细化views.py的功能

from backend.utils import check_code as CheckCode

def check_code(request):
"""
获取验证码
:param request:
:return:
""" stream = io.BytesIO()#在内存开辟一块儿空间
# 创建随机字符 code 2234
# 创建一张图片img,将随机字符串2234写到图片上
img, code = CheckCode.create_validate_code() img.save(stream, "PNG")# 将图片放到内存中,以png形式,也可以以其他形式
# 将字符串形式的验证码2234放在Session中
request.session["CheckCode"] = code
return HttpResponse(stream.getvalue())#再从内存取出来给用户

 c、在urls.py中

from django.conf.urls import url
from web.views import account urlpatterns = [ url(r'^check_code/$', account.check_code), ]

 d、前端的验证码img标签的src属性指向这个地址,就能自动获取到图片

<span>
<img class="check-img" src="/check_code/" alt="验证码" onclick="ChangeCode(this);">
</span> =====================================
<script>
function ChangeCode(ths) {
ths.src += '?';
}
</script>

3、生成邮箱验证码、发送邮件

 在commons.py中,定义函数生成随机数

'''
1.生成邮箱验证码
2.
'''
import random def random_code():
#生成邮箱验证码
code = ''
for i in range(4):#循环4次
current = random.randrange(0,4)
if current != i:#生成字母
temp = chr(random.randint(65,90))
else:
temp = random.randint(0,9)
code += str(temp)#每一次的数字拼接起来
return code

在message.py中配置邮箱,调用即可发送邮件

#配置邮箱,调用即可发送邮件
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr def email(email_list, content, subject="抽屉新热榜-用户注册"):
#发送设置
msg = MIMEText(content, 'plain', 'utf-8')
msg['From'] = formataddr(["抽屉新热榜",'wptawy@126.com']) #设置发件人,发件地址
msg['Subject'] = subject #主题 #服务器的设置
# SMTP服务,随便哪个邮箱都可以,但是要可以设置开启smtp服务
server = smtplib.SMTP("smtp.126.com", 25)#连接**服务器,**端口
server.login("wptawy@126.com", "JUEmimima")#登录名,密码
server.sendmail('wptawy@126.com', email_list, msg.as_string())#email_list发送列表
#自己的邮箱、发送列表、发送内容
server.quit() #调用方法
# email(['xiaohu@live.com','jinxin@live.com'], 'xiaohuzuishuai')

4、递归实现评论树

实现评论树时,需要对后端和前端分别操作

后端:将数据库中取出的数据构造成父评论中有子评论,子评论中有孙子评论,这样的树状字典结构,将这样的数据以json格式传到前端。

前端:采用递归方式,将后端穿过来的数据,一层一层的拿评论,动态的生成父标签、子标签、孙子标签 。有两种方式:、

方式一:前端通过js语句,以递归方式,动态的生成标签,将递归的压力转移给用户。

方式二:采用自定义标签方式,用.py文件来处理递归函数,生成标签树后,再返回给前端,用mark_safe()包一下返回值。

后端:views.py中

def comment_sj(request):
#评论实现
news_id = 1
# comment_list = models.Comment.objects.filter(news_id=news_id)
# for row in comment_list:
# print(row.id,row.comment,row.news_id,row.user_info.name,row.parent_id) comment_list =[
{'id':1,'comment':'python最牛逼','user':'搞基建','parent_id':None},
{'id':2,'comment':'java最牛逼','user':'搞基建','parent_id':None},
{'id':3,'comment':'php最牛逼','user':'搞基建','parent_id':None},
{'id':4,'comment':'胡说','user':'小B虎','parent_id':1},
{'id':5,'comment':'我最帅','user':'李欢','parent_id':1},
{'id':6,'comment':'郭永昌时...','user':'郭永昌','parent_id':4},
{'id':7,'comment':'郭永昌时2...','user':'郭永昌2','parent_id':4},
] # 将comment_list_dict 构造成{
# 1:[],
# 2:[],
# }
comment_list_dict = {}
for item in comment_list:
item.update({'children':[]}) #给每一行加上children列表
comment_list_dict[item['id']] = item
# print(comment_list_dict) #字典为引用类型
ret = []
for item in comment_list:
current_row_parent_id = item['parent_id']
if not current_row_parent_id:#current_row_parent_id 为空
ret.append(item)
else: #current_row_parent_id 当前行父亲id不为空时,找到父亲行,把自己加到父亲行的children里面
#法一:
# for r in comment_list:
# if r['id'] == current_row_parent_id:
# r['children'].append(item)
#法二:使用comment_list_dict字典
comment_list_dict[current_row_parent_id]['children'].append(item)
# print(ret)
#方式一:ajax请求后直接返回数据
import json
return HttpResponse(json.dumps(ret))
#方式二:跳转到另一个页面,采用自定义标签方式,展示评论树
#return render(request,'comment_load.html',{'ret':ret}) def comment(request):
return render(request,'comment.html')

  urls.py中

from django.conf.urls import url
from django.contrib import admin
from app01 import views urlpatterns = [ url(r'^comment_sj/', views.comment_sj),
url(r'^comment/', views.comment),]

 前端中:评论应是点击后再显示,应以ajax形式发送

comment.html中,前端评论树生成方式一:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.comment_box{
margin-left: 45px;
}
</style>
</head>
<body>
<div class="item">
<a news_id="17" class="com">评论</a>
{# <div class="comment_box"><span>父评论</span>#}
{# <div class="comment_box"><span>字1评论</span>#}
{# </div>#}
{# <div class="comment_box"><span>字2评论</span>#}
{# <div class="comment_box"><span>孙子评论</span>#}
{# </div>#}
{##}
{# </div>#}
</div>
</div> <div class="item">
<a news_id="17" class="com">评论</a>
</div> <script src="/static/js/jquery-2.1.4.min.js"></script>
<script>
$(function () {
bindCommentEvent();
}); function bindCommentEvent() {
$('.com').click(function () {
var news_id = $(this).attr('news_id');
var _this = $(this); $.ajax({
url:'/comment_sj',
type:'GET',
data:{news_id:news_id},
dataType:'JSON',//第二种方式是,这个地方要改成html!!!!
success:function (arg) {
console.log(arg);
//方式一:(推荐此方法,将递归的压力分解给用户)
create_tree(arg,_this);
//方式二:用render返回另一个.html页面,页面里面放数据,数据由.py文件生成
//_this.after(arg);
}
})
})
} function diGui(children_list) {
var htm = '';
$.each(children_list,function (ck,cv) {
var b = '<div class="comment_box"><span>';
b += cv.comment+'</span>'; var result = diGui(cv.children);
b += result;
b +='</div>';
htm += b;
});
return htm;
} function create_tree(data,$this) {
var htm = '<div class="comment_box">';//父评论框
//父评论内容
$.each(data,function (k,v) {
{# console.log(data);#}
var a = '<div class="comment_box"><span>';
a += v.comment+'</span>'; //下一级子评论内容加在这里这里调用函数来生成子评论
var result = diGui(v.children);
a += result; a +='</div>';
htm += a;
});
htm += '</div>';
$this.after(htm); /* 此处应该是after,而不是append,append时加在标签里面,after时加在标签下面*/
{# console.log(htm)#}
}
</script> </body>
</html>

 前端,评论树生成方式二: 

方式二示例:

comment_load.html中采用方式二:

{% load laogao %}
{% create_tree ret %}

  在 templetetags文件夹中的 laogao.py文件中:

# 方式二:此py文件创建评论树,待.html文件加载

from django import template
from django.utils.safestring import mark_safe register = template.Library()
def diGui(children_list):
htm = ''
for cv in children_list:
b = '<div class="comment_box"><span>'
b += cv['comment'] + '</span>'
result = diGui(cv['children'])
b += result
b += '</div>'
htm += b
return htm @register.simple_tag
def create_tree(ret):
htm = '<div class="comment_box">'
for v in ret:
b = '<div class="comment_box"><span>'
b += v['comment'] + '</span>'
b += diGui(v['children'])
b += '</div>'
htm += b
htm += '</div>'
return mark_safe(htm)

 5、组合搜索(Q)

两种方式

方式一:手动添加Q对象操作

方式二:动态的生成Q对象来操作, 此方式也可用于组合搜索

===========方式一=============

obj = models.UserInfo.objects.filter(Q(Q(username=n) & Q(pwd=p)) | Q(Q(email=e) & Q(pwd=p)) ).first()

===========方式二==========
# 组合搜索
from django.db.models import Q con = Q()
q1 = Q()
q1.connector = 'AND'
q1.children.append(('email',value_dict['email']))
#即 q1(email = value_dict['email'])
q1.children.append(('password',value_dict['pwd'])) q2 = Q()
q2.connector = 'AND'
q2.children.append(('username', value_dict['user']))
q2.children.append(('password', value_dict['pwd'])) con.add(q1,'OR')
con.add(q2,'OR') obj = models.UserInfo.objects.filter(con).first()
if not obj:
rep.message = {'user':[{'message':'用户名邮箱或密码错误'}]}

  

  

Django 六——自定义标签、图片验证码、发送邮件、评论树、组合搜索的更多相关文章

  1. Django之自定义标签,过滤器,以及inclusion_tag

    目录 Django之自定义标签,过滤器,以及inclusion_tag 自定义过滤器 自定义标签 inclusion_tag inclusion_tag() 项目实例: inclusion_tag() ...

  2. 潭州课堂25班:Ph201805201 django 项目 第九课 图片验证码前台实现,判断用户是否注册功能实现 (课堂笔记)

    u胎代码实现 : 针对每一个 app 写个 js 脚本, 先给 users 的 app 应用创建个 js:在指定目录下的 js 文件夹下,创建 users 文件夹,下创建 suth.js ,图片验证 ...

  3. Django模板自定义标签和过滤器,模板继承(extend),Django的模型层

    上回精彩回顾 视图函数: request对象 request.path 请求路径 request.GET GET请求数据 QueryDict {} request.POST POST请求数据 Quer ...

  4. django中自定义标签和过滤器

    想要实现自定义标签和过滤器需要进行准备工作: 准备(必需)工作: 1  在某个app下创建一个名为templatetags(必需,且包名不可变)的包.假设我们在名为polls的app下创建了一个tem ...

  5. django模板-自定义标签、过滤器

    自定义标签或者过滤器的步骤 ①将要创建自定义标签或过滤器的app加入settings文件的installed_apps中 ②在app中创建templatetags目录,类型为包即packages ③在 ...

  6. Django的自定义标签

    Django提供了自定义标签功能,可以方便常用方法的重复使用. 标签的本质就是函数,标签名就是函数名. 注意点: 1.需要到django.template对象. 2.register = templa ...

  7. Django下自定义标签和过滤器

    ---恢复内容开始--- 第一步:确保setting中的INSTALL_APPS配置当前的app,要不然Django无法找到自定义的simple_tag. 第二步:在app中创建templatetag ...

  8. JSP自定义标签——调用数据库(通过id号搜索相关信息)

    一.创建新表(假设在master数据库下新建) 二.连接数据库 开始-->控制面板-->管理工具-->数据源-->系统DSN-->添加-->SQL Server-- ...

  9. 潭州课堂25班:Ph201805201 django 项目 第十课 自定义错误码,完成图片验证码,用户是否被注册功能 (课堂笔记)

    把 视图传到前台的  JsonResponse(data=data) 先进行处理,之后再传到前台, 处理:引用自定义错误代码,把错误代码返回给前台,前台根据错误代码中文提示 class Code: O ...

随机推荐

  1. Sometimes it takes going through something so awful to realize the beauty that is out there in this world.

    Sometimes it takes going through something so awful to realize the beauty that is out there in this ...

  2. mui蒙版使用例子

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <meta name=& ...

  3. 关于com工程依赖的一些总结

    作者:朱金灿 来源:http://blog.csdn.net/clever101 一是com组件工程的依赖设置.比如A这个组件工程要使用B组件工程的类,要如何设置呢?具体就是先把在A工程里加上B工程的 ...

  4. TX Text Control X10独家揭秘之使用对象作为数据源

    文档处理控件TX Text Control即将发布的X10版本,将升级重点还是放到了其比较优势的流式布局报表设计和生成上.慧都获得了来自其开发商Text Control GmbH公司的一手资料,迫不及 ...

  5. 46 Simple Python Exercises-Very simple exercises

    46 Simple Python Exercises-Very simple exercises 4.Write a function that takes a character (i.e. a s ...

  6. 更新浏览器,导致编写脚本报错Message: Unable to find a matching set of capabilities

    卸载更新浏览器后,所编写的脚本无法运行,报如下的错误:selenium.common.exceptions.WebDriverException: Message: Unable to find a ...

  7. C#实现正则表达式

    如果想了解正则表达式的基础知识:http://www.cnblogs.com/alvin-niu/p/6430758.html 一.C#中的Regex类 1.在C#中开发正则表达式,首先要引用Syst ...

  8. StringBuffer是可变的还是不可变的?

    前言:我们知道String类的修饰符是final,其char[] value也是由final修饰的,每次给String变量赋一个新值,都会创建一个新的String对象,很多有涉及到字符串本身的改变都是 ...

  9. Go - 环境安装

    目录 你好,Go语言 环境安装 目录结构 命令 开发工具 学习网址 小结 你好,Go语言 Go 是一个开源的编程语言,它能让构造简单.可靠且高效的软件变得容易. 因工作需要,准备入坑,先从环境安装开始 ...

  10. GPU并行编程:内核及函数的实现

    原文链接 回想一下我们之前在设备上使用“kernelFunction<<<1,1>>>(..)”执行一个函数的代码,我在那里还曾说过后面会细说,本文就详细介绍一下参 ...