今日学习内容
具体项目:D:\pythonProject\django_day60
登录界面搭建
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1 class="text-center">用户登录</h1>
<form id="id_form">
{% csrf_token %}
<div class="form-group">
<label for="id_username">用户名</label>
<input type="text" id="id_username" name="username" class="form-control">
</div>
<div class="form-group">
<label for="id_password">密码</label>
<input type="password" id="id_password" name="password" class="form-control">
</div>
<div class="form-group">
<label for="id_code">验证码</label>
<div class="row">
<div class="col-md-6">
<input type="text" id="id_code" name="code" class="form-control">
</div>
<div class="col-md-6">
<img src="/get_code/" id="id_img" alt="" width="285px" height="30px">
</div>
</div>
</div>
<div class="form-group text-center">
<div class="row">
<div style="position: relative"><input type="button" value="登录" class="btn btn-success" id="id_submit"></div>
<div style="margin: 20px -20px 0 0"> <span class="text-danger error"></span></div>
</div>
</div>
</form>
</div>
</div>
</div>
</body>
登录功能后端和前端
后端 views.py
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
else:
# 前端输入的用户名,密码,验证码,校验用户名和密码
res = {'code': 100, 'msg': '登录成功!'}
# print(request.POST)
code = request.POST.get('code')
username = request.POST.get('username')
password = request.POST.get('password')
# 获取后端的验证码 存于session中。
old_code = request.session.get('code')
if code.lower() == old_code.lower():
user = authenticate(username=username, password=password)
if user:
# 登录成功,返回json格式字符串
return JsonResponse(res)
else:
res['code'] = 101
res['msg'] = '用户名或密码错误'
return JsonResponse(res)
else:
res['code'] = 102
res['msg'] = '验证码错误'
return JsonResponse(res)
def get_rgb():
return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
def get_code(request):
# 方式一,直接返回一张图片,启动文件路口是manage.py
# with open('./media/avatar/my.png', 'rb') as f:
# data = f.read()
#
# return HttpResponse(data)
# 方式二:自己生成一张图片,返回,借助模块,pillow
# 参数1:rgb:三原色 red green blue
# 参数2:宽度和高度
# 参数3:三原色的色值 0-255
# 创建图片
# img = Image.new('RGB', (285, 30), (0, 255, 255))
# #保存到本地
# with open('my.png', 'wb') as f:
# img.save(f)
# with open('./my.png', 'rb') as f:
# data = f.read()
# return HttpResponse(data)
# 方式三:生成的图片写到内容中
# 创建图片
# img = Image.new('RGB', (285, 30), (0, 0, 0))
# # 保存到内存
# byte_io = BytesIO()
# img.save(byte_io, 'png') # 指定图片格式
# # 从BytesIO取出二进制,返回给前端
# return HttpResponse(byte_io.getvalue())
# 方式四:在图片上写文字
# 创建图片
# img = Image.new('RGB', (285, 30), (0, 0, 0))
# # 在图片上写文字,相当于画板
# img_draw = ImageDraw.Draw(img)
# img_draw.text((0, 0), "xzwyb")
# # 保存到内存
# bytes_io = BytesIO()
# img.save(bytes_io, 'png') # 指定图片格式
# # 从BytesIO取出二进制,返回给前端
# return HttpResponse(bytes_io.getvalue())
# 方式五:图片上写文字,字体是指定的字体,指的颜色是随机
# img = Image.new('RGB', (285, 30), (0, 0,0))
# #创建一个字体对象
# font = ImageFont.truetype('./static/font/font1.ttf', 30)
# #在图片上写文字,相当于画板
# img_draw = ImageDraw.Draw(img)
# img_draw.text((0, 0), "xzwyb", font=font)
# #保存到内存上
# byte_io = BytesIO()
# img.save(byte_io, 'png') #指定图片格式
# #从BytesIO取出二进制,返回给前端
# return HttpResponse(byte_io.getvalue())
# 方式六:终极方案自己造,验证码
# img = Image.new('RGB', (285, 30), get_rgb())
img = Image.new('RGB', (200, 30), (255, 255, 255))
# 创建一个字体对象
font = ImageFont.truetype('./static/font/font1.ttf', 20)
# 在图片上写字
img_draw = ImageDraw.Draw(img)
# 在图片上写文字(数字,大写字母,小写字母组合 5个)
code_str = ''
for i in range(5):
num = random.randint(0, 9)
upper = chr(random.randint(65, 90))
lowe = chr(random.randint(97, 122))
ran = str(random.choice([num, upper, lowe]))
code_str += ran # python 是强类型语言,不同类型直接不能直接相加,需要类型转换
img_draw.text((50 + i * 20, 10), ran, fill=get_rgb(), font=font)
print(code_str)
################
request.session['code'] = code_str # 重点,存到session中,下次从session中取出来比较
################
# #在图片上画点划线
width = 285
height = 30
for i in range(10):
x1 = random.randint(0, width)
x2 = random.randint(0, width)
y1 = random.randint(0, height)
y2 = random.randint(0, height)
# 画线
img_draw.line((x1, y1, x2, y2), fill=get_rgb())
for i in range(50):
# 画点
img_draw.point([random.randint(0, width), random.randint(0, height)], fill=get_rgb())
x = random.randint(0, width)
y = random.randint(0, height)
# 画弧线
img_draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_rgb())
# 保存到内存
bytes_io = BytesIO()
img.save(bytes_io, 'png')
# 从BytesIO取出二进制,返回给前端
return HttpResponse(bytes_io.getvalue())
点击图片验证码更新以及验证码发送
<script>
$("#id_img").click(function () {
//图片的src地址变成原地址
//alter($(this)[0].src)
var timestamp = new Date().getTime()
$(this)[0].src = '/get_code/?t=' + timestamp
})
$("#id_submit").click(function (){
//取出填入的数据,发送ajax的post请求
//$('#id_form').serializeArray()
$.ajax({
url:'/login/',
type:'post',
data: {
"username": $('#id_username').val(),
'password': $('#id_password').val(),
'code': $('#id_code').val(),
'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val(),
//根据属性取标签
},
success:function (data){
console.log(data)
if(data.code == 100){
location.href='/index/'
}else{
$('.error').html(data.msg)
}
}
})
})
</script>
首页导航和首页轮播图
前端页面搭建
通过bootstrap
中文网,来cope 修改代码。
轮播图 models.py
class Banner(models.Model):
name = models.CharField(max_length=32)
img = models.FileField(upload_to='banner', default='./media/banner/banner1.png')
link = models.CharField(max_length=32) # 点击轮播图跳转的地址
class Meta:
verbose_name_plural = '轮播图表'
def __str__(self):
try:
return '图名: %s/跳转地址: %s' % (self.name, self.link)
except:
return '图名:%s' % (self.name)
页面文章列表页面
admin 后台录入数据,文章录入数据
admin 是django的一个app,它是后台管理,内置的,方便我们做第二次开发和录入数据。
在app的admin.py 把表注册一下,登录到后台可以看到
admin.site.register(UserInfo)
admin.site.register(Article)
admin.site.register(Blog)
admin.site.register(Tag)
admin.site.register(Category)
admin.site.register(UpAndDown)
admin.site.register(Comment)
admin.site.register(Banner)
直接录入数据,跟在数据表录入数据的本质一样的。
注意:需要在models.py中将表名变成中文展示在admin后台管理需要
class Meta:
verbose_name_plural = '用户表' # 后台管理显示中文
打印的时候,方便查询
def __str__(self):
return self.name
开启media访问
1.上传的图片,目前访问不到,要啊开启media的访问,才能看到图片。
2.开启media访问,本质就是把项目中某个目录可以让客户端(浏览器)直接访问。这是很危险的所以media下不能放重要的东西。
3.本身static 文件夹从浏览器可以访问,默认这个目录已经开放。
如果开启
配置文件中:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
在路由中
path('media/<path:path>',serve, {'document_root':settings.MEDIA_ROOT}),
图片防盗链
有的网站有上传图片的功能,我们可以把图片上传上去,然后在自己的网站中使用,这样不会消耗我们自己网站的宽带,比如cnblogs,cnblogs就屏蔽了这种行为,这就是图片防盗链。
本质原理:
因为发送http请求,请求头中有个参数叫referer,是个url地址,它表示上一次访问的地址。
图片防盗链可以通过这个来控制,判断一下refeer是不是我们自己的地址,如果不是就不返回。
通过请求头中得referer来控制不做非自己的地址请求。
标签:code,return,img,randint,python,random,学习,Day62,get
From: https://www.cnblogs.com/bjyxxc/p/16704658.html