Python_Django系列_3.视图,模板
前言
一、视图
#1.无参数情况
def hello(request):
return HttpResponse("Hello World")
#2.传递一个或多个参数
def helloParam(request,param1,param2):
return HttpResponse("The param is : " + param1+param2)
#include,参数name,命名空间namespace
#第二钟方法命名空间app_name = 'myblog' #十分重要的
<a href="{% url 'First:getform' %}#页面跳转
path('getform/', views.search, name='getform'),
path('',include(('First.urls','First'),namespace='First'))#跳转子模块,
path('verify_code/',views.verify_code,name='verify_code')#验证码
#参数
path('/<int:question_id>', views.detail, name='detail'),
#通过HttpResponse来返回视图
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
template = loader.get_template('myblog/index.html')
context = {
'latest_question_list': latest_question_list,
}
return HttpResponse(template.render(context, request))
#render来返回视图
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'latest_question_list': latest_question_list}
return render(request, 'polls/index.html', context)
def detail(request, question_id):
return HttpResponse("You're looking at question %s." % question_id)
#捕捉异常404
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)#get_list_or_404()多个
return render(request, 'myblog/detail.html', {'question': question})
# def detail(request, question_id):
# try:
# question = Question.objects.get(pk=question_id)
# except Question.DoesNotExist:
# raise Http404("Question does not exist")
# return render(request, 'myblog/detail.html', {'question': question})
二、模板
1.模板语言
模板语言包括4种类型
● 变量
● 标签
● 过滤器
● 注释
小于号< 转换为 (<);
大于号> 转换为 (>);
单引号' 转换为 (');
双引号" 转换为 (");
与符号& 转换为 (&);
{{变量}}
#标签
#for标签
{% for x in 列表 %}
# 列表不为空时执行
{% empty %}
# 列表为空时执行
{% endfor %}
#可以通过{{ forloop.counter }}得到for循环遍历到了第几次
#if标签
{% if 条件 %}
{% elif 条件 %}
{% else %}
{% endif %}
{%for book in list%}
{%if book.id <= 2%}
<li style="background-color: red;">{{book.btitle}}</li>
{%elif book.id <= 3%}
<li style="background-color: blue;">{{book.btitle}}</li>
{%else%}
<li style="background-color: green;">{{book.btitle}}</li>
{%endif%}
{%empty%}
<li>对不起,没有图书</li>
{%endfor%}
#过滤器 变量|过滤器:参数
#length:长度
#default:设置模板变量的默认值
#{{content|safe}}
#date:改变日期的显示格式,常用的格式化字符如下:
#forloop.counter{{ forloop.counter }}是Django模板系统专门提供的一个变量,用来表示你当前循环的次数,一般用来给循环项目添加有序数标。
#● Y表示年,格式为4位,y表示两位的年
#● m表示月,格式为01,02,12等
#● d表示日, 格式为01,02等
#● j表示日,格式为1,2等
#● H表示时,24进制,h表示12进制的时
#● i表示分,为0-59
#● s表示秒,为0-59
{{book.bpub_date}}
---格式化时间为:
{{book.bpub_date|date:"Y-m-j"}}
2.模板继承
#base.html
{% block b1 %}
<h1>这是父模板b1块中的内容</h1>
{% endblock b1 %}
{% block b2 %}
<h1>这是父模板b2块中的内容</h1>
{% endblock b2 %}
#son.html
# 子模板去继承父模板之后,可以重写父模板中的某一块的内容
{% extends 'base.html' %}
{% block b2 %}
# 获取父模板中块的默认内容
{{ block.super }}
# 重写的内容
<h1>这是子模板b2块中的内容</h1>
{% endblock b2 %}
3.CSRF (跨站请求伪造)
#第一个方式view
@csrf_exempt
#第二个方式form
{% csrf_token %}
#第三个方式ajax
csrfmiddlewaretoken: '{{ csrf_token }}'
三、特殊模块
1.验证码
第一种方式
#验证码函数
def verify_code(request):
# 引入随机函数模块
import random
# 定义变量,用于画面的背景色、宽、高 RGB
bgcolor = (random.randrange(20, 100), random.randrange(
20, 100), 255)
width = 100
height = 25
# 创建画面对象
im = Image.new('RGB', (width, height), bgcolor)
# 创建画笔对象
draw = ImageDraw.Draw(im)
# 调用画笔的point()函数绘制噪点
for i in range(0, 100):
xy = (random.randrange(0, width), random.randrange(0, height))
fill = (random.randrange(0, 255), 255, random.randrange(0, 255))
draw.point(xy, fill=fill)
# 定义验证码的备选值
str1 = 'ABCD123EFGHIJK456LMNOPQRS789TUVWXYZ0'
# 随机选取4个值作为验证码
rand_str = ''
for i in range(0, 4):
rand_str += str1[random.randrange(0, len(str1))]
# 构造字体对象,(设置自己的)
font = ImageFont.truetype('../static/font/SIMYOU.TTF', 23)
# 构造字体颜色
fontcolor = (255, random.randrange(0, 255), random.randrange(0, 255))
# 绘制4个字
draw.text((5, 2), rand_str[0], font=font, fill=fontcolor)
draw.text((25, 2), rand_str[1], font=font, fill=fontcolor)
draw.text((50, 2), rand_str[2], font=font, fill=fontcolor)
draw.text((75, 2), rand_str[3], font=font, fill=fontcolor)
# 释放画笔
del draw
# 存入session,用于做进一步验证
request.session['verifycode'] = rand_str
# 内存文件操作
buf = BytesIO()
# 将图片保存在内存中,文件类型为png
im.save(buf, 'png')
# 将内存中的图片数据返回给客户端,MIME类型为图片png
return HttpResponse(buf.getvalue(), 'image/png')
#html文件
<input type="text" class="form-control" name="yzm">
<img id="yzm" src="{% url 'verify_code' %}"/>
#验证视图
yzm=request.POST.get('yzm')
verifycode=request.session['verifycode']
if yzm == verifycode:
第二种方式
#1. 安装第三方库:
pip install django-simple-captcha
#2.在settings中,将‘captcha’注册到app列表里
#3. 在根目录下的urls.py文件中增加:
path('captcha/', include('captcha.urls')) # 增加这一行
# 4. captcha = CaptchaField(label='验证码')
#5. 点击更换验证码:
$('.captcha').click(function () { $.getJSON("/captcha/refresh/", function (result) { $('.captcha').attr('src', result['image_url']); $('#id_captcha_0').val(result['key']) }); }); </script>
在这里插入代码片
2.Session的使用
# 这是所有会话对象的基类,包含标准的字典方法:
1.__getitem__(key)
fav_color = request.session['fav_color']
2.__setitem__(key, value)
request.session['fav_color'] = 'blue'
3.__delitem__(key)
del request.session['fav_color'] # 如果不存在会抛出异常
4.__contains__(key)
'fav_color' in request.session
5.get(key, default=None)
fav_color = request.session.get('fav_color', 'red')
6.pop(key, default=__not_given)
fav_color = request.session.pop('fav_color', 'blue')
# 类似字典数据类型的内置方法
keys()
items()
setdefault()
clear()
flush()#删除当前的会话数据和会话cookie。
set_expiry(value) # 设置cookie的有效期。可以传递不同类型的参数值:
• 是一个整数,session将在对应的秒数后失效。例如request.session.set_expiry(300) 将在300秒后失效.
• 是一个datetime或者timedelta对象, 会话将在指定的日期失效
• 为0,在用户关闭浏览器后失效
• 为None,则将使用全局会话失效策略失效时间从上一次会话被修改的时刻开始计时。
get_expiry_age()
# 返回多少秒后失效的秒数。对于没有自定义失效时间的会话,这等同于SESSION_COOKIE_AGE.
# 这个方法接受2个可选的关键字参数
• modification:会话的最后修改时间(datetime对象)。默认是当前时间。
•expiry: 会话失效信息,可以是datetime对象,也可以是int或None
get_expiry_date()# 和上面的方法类似,只是返回的是日期
get_expire_at_browser_close() # 返回True或False,根据用户会话是否是浏览器关闭后就结束。
if request.session.get('is_login', None): # 不允许重复登录
return redirect('myblog:index_q')
3.密码加密
使用Python内置的hashlib库,使用哈希值的方式加密密码
def hash_code(s, salt='mysite'):# 加点盐
h = hashlib.sha256()
s += salt
h.update(s.encode()) # update方法只接收bytes类型
return h.hexdigest()
if user.password == hash_code(password):
new_user.password = hash_code(password1)
总结
当然远远不至于此,还得披星戴月!