修改密码
后台
@login_required(login_url='/login/')
def change_password(request):
# 1 取出原密码---校验原密码是否正确
old_password = request.POST.get('old_password')
if request.user.check_password(old_password):
new_password = request.POST.get('new_password')
re_new_password = request.POST.get('re_new_password')
# 2 取出新密码和确认新密码
if new_password == re_new_password:
request.user.set_password(new_password)
request.user.save() # 一定不要忘了
return JsonResponse({'code': 100, 'msg': '修改成功'})
else:
return JsonResponse({'code': 101, 'msg': '两次密码不一致'})
else:
return JsonResponse({'code': 102, 'msg': '原密码错误'})
前台
<div>
<div class="modal fade" tabindex="-1" role="dialog" aria-labelledby="gridSystemModalLabel"
id="gridSystemModal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title" id="gridSystemModalLabel">修改密码</h4>
</div>
<div class="modal-body">
<div class="alert alert-warning alert-dismissible fade in hidden" role="alert"
id="alert_error">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span
aria-hidden="true">×</span></button>
<strong>密码修改成功</strong>
</div>
<form>
{% csrf_token %}
<div class="form-group">
<label for="">原密码</label>
<input type="password" name="old_password" class="form-control">
</div>
<div class="form-group">
<label for="">新密码</label>
<input type="password" name="new_password" class="form-control">
</div>
<div class="form-group">
<label for="">确认新密码</label>
<input type="password" name="re_new_password" class="form-control">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="id_submit">确定</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</div>
$('#id_submit').click(function () {
// 让按钮不可点击
//$(this).addClass('disabled')
// jquery 都是给标签修改属性--attr-自定义属性和prop->自有属性的区别
$(this).prop('disabled', true)
$.ajax({
url: '/change_password/',
method: 'post',
data: {
old_password: $('[name="old_password"]').val(),
new_password: $('[name="new_password"]').val(),
re_new_password: $('[name="re_new_password"]').val(),
csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val()
},
success: function (data) {
console.log(data)
// 显示错误信息,并显示
$('#alert_error').removeClass('hidden').children('strong').html(data.msg)
// 让按钮可以点击
$('#id_submit').prop('disabled', false)
if (data.code == 100) {
$('#alert_error').addClass('hidden')
// 模态框消失
$('#gridSystemModal').modal('hide')
// 跳到登录,重新登录
location.href = '/login/'
} else {
// 3s 后,错误提示消失
setTimeout(function () {
$('#alert_error').addClass('hidden')
}, 3000)
}
}
})
})
轮播图
轮播图----多张大小完全一致 ——介于 数据库中找
render显示
后台
def index(request):
# 取出所有文章--》没有加分页
article_list = Article.objects.all().order_by('create_time')
# 推荐文章--》按阅读数高的排-->取5条
# article_hot = Article.objects.all().order_by('点赞数')
# 去 banner表中取出头三张轮播图图片---》把对象---》转成--》列表套字典形式
'''
[{url:/media/banner/1.png,msg:广告,to:'/article/1.html/'},{url:/media/banner/1.png,msg:广告,to:'/article/1.html/'}]
'''
banner_list = [
{'url': '/media/banner/1.png', 'msg': '我们有篇好文章欢迎你观看', 'to': '/article/1.html/'},
{'url': '/media/banner/2.png', 'msg': '快来注册把', 'to': '/register/'}, ]
return render(request, 'index.html', {'article_list': article_list, 'banner_list': banner_list})
前台
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
<li data-target="#carousel-example-generic" data-slide-to="1"></li>
</ol>
<div class="carousel-inner" role="listbox">
{% for banner in banner_list %}
{% if forloop.first %}
<div class="item active">
{% else %}
<div class="item">
{% endif %}
<a href="{{ banner.to }}">
<img src="{{ banner.url }}" alt="..." class="img">
<div class="carousel-caption">
{{ banner.msg }}
</div>
</a>
</div>
{% endfor %}
<!-- Controls -->
<a class="left carousel-control" href="#carousel-example-generic" role="button"
data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#carousel-example-generic" role="button"
data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
ajax显示
后端
def get_banner(request):
banner_list = [
{'url': '/media/banner/3.png', 'msg': '看yy', 'to': '/login/'},
{'url': '/media/banner/3.png', 'msg': '看xx', 'to': 'http://www.baidu.com'}, ]
return JsonResponse({'code': 100, 'results': banner_list})
前端
js 渲染轮播图---》之前用render渲染轮播图---》当页面加载成功---》发送ajax--》获取图片---》使用js写在页面上
$(function () {
// 发送ajax请求
$.ajax({
url: '/get_banner/',
method: 'get',
success: function (data) {
console.log(data)
// js 写到页面上
$('.img').each(function (i, v) {
console.log(i)
console.log(v)
// v 是原生dom对象,不是jq的对象,使用$(v) 转成jq对象,支持链式调用
$(v).attr('src', data.results[i].url).parent().attr('href', data.results[i].to).children('div').html(data.results[i].msg)
})
}
})
})
个人站点页面
# 设计 路由
# 路由
# 个人站点路由放最后---》上面所有都匹配完了--->再看是不是个人站点
path('<str:username>', views.site),
# re_path('(?P<username>\w+)', views.site),
# 视图函数
def site(request, username):
# 个人站点不存在---》根据用户名查不到用户,就是404
user = UserInfo.objects.filter(username=username).first()
if user:
# 查出当前用户,所有的文章
article_list = Article.objects.filter(blog_id=user.blog.id).all()
# article_list=Article.objects.filter(blog=user.blog).all()
return render(request, 'site.html', locals())
else:
return render(request, '404.html')
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/static/js/jquery.min.js"></script>
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
{% block header %}
{% endblock %}
</head>
<body>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">博客园</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">文章 <span class="sr-only">(current)</span></a></li>
<li><a href="#">新闻</a></li>
</ul>
{% if request.user.is_authenticated %}
<ul class="nav navbar-nav navbar-right">
<li><a href="#">{{ request.user.username }}</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria-haspopup="true"
aria-expanded="false">更多操作 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">后台管理</a></li>
<li><a href="#"><span data-target="#gridSystemModal" data-toggle="modal">修改密码</span></a>
</li>
<li><a href="#">修改头像</a></li>
<li role="separator" class="divider"></li>
<li><a href="/logout/">退出</a></li>
</ul>
</li>
</ul>
{% else %}
<ul class="nav navbar-nav navbar-right">
<li><a href="/login/">登录</a></li>
<li><a href="/register/">注册</a></li>
</ul>
{% endif %}
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
{% block left %}
{% endblock %}
</div>
<div class="col-md-9">
{% block content %}
{% endblock %}
</div>
</div>
</div>
</body>
</html>
site.html
{% extends 'base.html' %}
{% block header %}
<link rel="stylesheet" href="/static/font-awesome/css/font-awesome.min.css">
{% endblock %}
{% block left %}
<div class="panel panel-primary">
<div class="panel-heading"><h3 class="panel-title">标签</h3></div>
<div class="panel-body">
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading"><h3 class="panel-title">分类</h3></div>
<div class="panel-body">
</div>
</div>
<div class="panel panel-danger">
<div class="panel-heading"><h3 class="panel-title">时间</h3></div>
<div class="panel-body"> Panel content</div>
</div>
{% endblock %}
{% block content %}
{% for article in article_list %}
<div class="media">
<h3 class="media-heading"><a href="">{{ article.title }}</a></h3>
<div class="clearfix">
<div class="media-left pull-right">
<a href="#">
<img alt="64x64" class="media-object" style="width: 64px; height: 64px;"
src="/media/{{ article.blog.userinfo.avatar }}">
</a>
</div>
<div class="media-body">
{{ article.desc }}
</div>
</div>
<div class="bottom-article pull-right" style="margin-top: 8px">
<span>posted @</span>
<span>{{ article.create_time|date:'Y-m-d H:i:s' }}</span>
<span class="glyphicon glyphicon-thumbs-up">{{ article.up_number }}</span>
<span><i class="fa fa-address-card-o"
style="margin-right: 10px"></i><span>{{ article.commit_number }}</span></span>
<span><a href="">编辑</a></span>
</div>
</div>
<hr>
{% endfor %}
{% endblock %}
侧边栏筛选
id title create_time create_date
1 快速认识什么是: 2023-12-08 11:22:35.329031 2023-12
2 c高并发必备技巧(三) 2023-12-08 11:22:59.018692 2023-12
3 虚拟机运行Hadoop 2023-12-08 11:23:19.949809 2023-12
5 基于DotNetty实现自动发布 2023-12-11 12:30:00.119046 2023-12
4 【UniApp】-uni-app概述 2023-12-08 11:23:43.763246 2023-11
后端
def site(request, username):
# 个人站点不存在---》根据用户名查不到用户,就是404
user = UserInfo.objects.filter(username=username).first()
if user:
# 查出当前用户(不是当前登录用户),所有的文章
article_list = Article.objects.filter(blog_id=user.blog.id).all()
# article_list=Article.objects.filter(blog=user.blog).all()
# 分类:比较复杂的查询---》查询当前传入名字的用户 ---》所有的分类---》及分类下文章数---》分组
# Category.objects.all().filter(blog=user.blog) # 当前用户所有分类查出来了
# 我们的目标是查询 当前用户 所有文章,按分类分组--》数每个分组下的文章数
'''
-annotate:
filter在annotate前:表示过滤,where条件
values在annotate前:表示分组的字段,如果不写表示按整个表分组
filter在annotate后:表示 having条件
values在annotate后:表示取字段---》只能取分组字段和聚合函数字段
'''
res_category = Article.objects.filter(blog=user.blog).values('category_id').annotate(
article_count=Count('id')).values(
'category__id', 'category__name', 'article_count')
print(res_category)
res_tag = Article.objects.filter(blog=user.blog).values('tag__id').annotate(article_count=Count('id')).values(
'tag__id', 'tag__name', 'article_count')
print(res_tag)
# 按时间分组--
# 查询当前站点下某年某月的文章数(分组依据,日期:年月),不需要连表
# from django.db.models.functions import TruncMonth, TruncDay, TruncYear, TruncHour
# Sales.objects
# .annotate(month=TruncMonth('timestamp')) # Truncate to month and add to select list
# .values('month') # Group By month
# .annotate(c=Count('id')) # Select the count of the grouping
# .values('month', 'c') # (might be redundant, haven't tested) select month and count
# '''
res_date = Article.objects.filter(blog=user.blog).annotate(create_date=TruncMonth('create_time')).values(
'create_date').annotate(aritcle_count=Count('id')).values('create_date', 'aritcle_count')
print(res_date)
return render(request, 'site.html', locals())
else:
return render(request, '404.html')
前端
{% block left %}
<div class="panel panel-primary">
<div class="panel-heading"><h3 class="panel-title">我的标签</h3></div>
<div class="panel-body">
{% for tag in res_tag %}
<p><a href="">{{ tag.tag__name }}({{ tag.article_count }})</a></p>
{% if not forloop.last %}
<hr>
{% endif %}
{% endfor %}
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading"><h3 class="panel-title">随笔分类</h3></div>
<div class="panel-body">
{% for category in res_category %}
<p><a href="">{{ category.category__name }}({{ category.article_count }})</a></p>
{% if not forloop.last %}
<hr>
{% endif %}
{% endfor %}
</div>
</div>
<div class="panel panel-danger">
<div class="panel-heading"><h3 class="panel-title">随笔档案</h3></div>
<div class="panel-body">
{% for item in res_date %}
<p><a href="">{{ item.create_date|date:'Y年m月' }}({{ item.aritcle_count }})</a></p>
{% if not forloop.last %}
<hr>
{% endif %}
{% endfor %}</div>
</div>
{% endblock %}