个人站点
# 退出登陆功能
未登陆时导航栏样式
已登陆时导航栏样式
urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^register/', views.register), # -- 注册
url(r'^login/', views.login), # -- 登陆
url(r'^get_code/', views.get_code), # -- 获取验证码
url(r'^home/', views.home), # -- 首页
url(r'^logout/', views.logout), # -- 退出登陆
]
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
views.py
from django.shortcuts import render, HttpResponse, redirect
from django.http import JsonResponse
from app01 import models
import hashlib
import random
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO, StringIO
def register(request):...
def get_random():...
def get_code(request):...
def login(request):...
def home(request):
return render(request, 'home.html', locals())
def logout(request):
request.session.flush()
return redirect('/home/')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
home.html
cv大法根据需求修改bootstrap导航栏的代码!
在get请求首页页面时,传递的locals()中是包含了request的,通过request可以取得session中的username值;
借此可以判断用户是否登陆!! 用Django的模版语法if-else-endif进行不同的展示!!
Ps: 退出登陆后,跳转登陆页面,发现浏览器里还有sessionid的存在,不要惊讶,这个是渲染登陆页面时验证码的session!!!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
{% load static %}
<script src="{% static 'layer-v3.5.1/layer/layer.js' %}"></script>
<title>Title</title>
</head>
<body>
{# 导航栏 #}
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">BBS</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
{% if request.session.username %}
<li><a href="#">{{request.session.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="#">修改头像</a></li>
<li><a href="#">后台管理</a></li>
<li role="separator" class="divider"></li>
<li><a href="/logout/">退出登陆</a></li>
</ul>
</li>
{% else %}
<li><a href="/login/">登陆</a></li>
<li><a href="/register/">注册</a></li>
{% endif %}
</ul>
</div>
</div>
</nav>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 修改密码功能
urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^register/', views.register), # -- 注册
url(r'^login/', views.login), # -- 登陆
url(r'^get_code/', views.get_code), # -- 获取验证码
url(r'^home/', views.home), # -- 首页
url(r'^logout/', views.logout), # -- 退出登陆
url(r'^set_pwd/', views.set_pwd), # -- 修改密码
]
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
views.py
from django.shortcuts import render, HttpResponse, redirect
from django.http import JsonResponse
from app01 import models
import hashlib
import random
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO, StringIO
def register(request):...
def get_random():...
def get_code(request):...
def login(request):...
def home(request):...
def logout(request):...
def set_pwd(request):
if request.method == "POST":
back_dic = {
'code': 200,
'msg': '修改成功!'
}
old_pwd = request.POST.get('old_pwd')
new_pwd = request.POST.get('new_pwd')
re_pwd = request.POST.get('re_pwd')
if not old_pwd:
back_dic['code'] = 1010
back_dic['msg'] = '旧密码不能为空!'
return JsonResponse(back_dic)
if not new_pwd:
back_dic['code'] = 1011
back_dic['msg'] = '新密码不能为空!'
return JsonResponse(back_dic)
if not re_pwd:
back_dic['code'] = 1012
back_dic['msg'] = '确认密码不能为空!'
return JsonResponse(back_dic)
if new_pwd != re_pwd:
back_dic['code'] = 1013
back_dic['msg'] = '新密码与确认密码不一致!'
return JsonResponse(back_dic)
# -- 验证愿密码是否正确!
m = hashlib.md5()
m.update(old_pwd.encode('utf-8'))
old_pwd = m.hexdigest()
res = models.UserInfo.objects.filter(username=request.session.get('username'), password=old_pwd).first()
if not res:
back_dic['code'] = 1014
back_dic['msg'] = '原密码不正确!'
return JsonResponse(back_dic)
# -- 修改密码的操作
m = hashlib.md5()
m.update(new_pwd.encode('utf-8'))
new_pwd = m.hexdigest()
# -- 不能单通过用户名进行筛选,因为用户名可能会重复,用session里的用户id!
models.UserInfo.objects.filter(id=request.session.get('id')).update(password=new_pwd)
back_dic['url'] = '/logout/'
return JsonResponse(back_dic)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
{% load static %}
<script src="{% static 'layer-v3.5.1/layer/layer.js' %}"></script>
<title>Title</title>
</head>
<body>
{# 导航栏 #}
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">BBS</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
{% if request.session.username %}
<li><a href="#">{{ request.session.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 data-toggle="modal" data-target=".bs-example-modal-sm">修改密码</a></li>
<li><a href="#">修改头像</a></li>
<li><a href="#">后台管理</a></li>
<li role="separator" class="divider"></li>
<li><a href="/logout/">退出登陆</a></li>
</ul>
</li>
{% else %}
<li><a href="/login/">登陆</a></li>
<li><a href="/register/">注册</a></li>
{% endif %}
</ul>
</div>
{# 点击修改密码 弹出的模态框 记得添加bs-example-modal-sm 这是官网示例代码的一个bug #}
<div class="modal fade bs-example-modal-sm" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="exampleModalLabel">修改密码</h4>
</div>
<div class="modal-body">
<form action="">
<div class="form-group">
<label for="username">用户名:</label>
{# 用户名不能修改,给个默认值 #}
<input type="text" id="username" class="form-control" disabled
value="{{ request.session.username }}">
</div>
<div class="form-group">
<label for="old_pwd">旧密码:</label>
<input type="password" id="old_pwd" class="form-control">
</div>
<div class="form-group">
<label for="new_pwd">新密码:</label>
<input type="password" id="new_pwd" class="form-control">
</div>
<div class="form-group">
<label for="re_pwd">确认密码:</label>
<input type="password" id="re_pwd" class="form-control">
</div>
</form>
</div>
<div class="modal-footer">
<div class="pull-right">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary edit">保存</button>
</div>
</div>
</div>
</div>
</div>
</div>
</nav>
<script>
$('.edit').click(function () {
let old_pwd = $('#old_pwd').val()
let new_pwd = $('#new_pwd').val()
let re_pwd = $('#re_pwd').val()
if (!old_pwd) {
layer.msg('请输入旧密码!')
return
}
if (!new_pwd) {
layer.msg('请输入新密码!')
return
}
if (!re_pwd) {
layer.msg('请输入确认密码!')
return
}
if (new_pwd !== re_pwd) {
layer.msg('新密码与确认密码不一致!')
return
}
$.ajax({
url: '/set_pwd/', // 为空提交到首页不合适,新开一个路由
type: 'post',
data: {
'old_pwd': old_pwd,
'new_pwd': new_pwd,
're_pwd': re_pwd,
'csrfmiddlewaretoken': '{{ csrf_token }}',
},
success: function (res) {
if (res.code == 200) {
layer.msg(res.msg, {icon: 1}, function () {
// 注册成功跳转指定页面
location.href = res.url
})
} else {
layer.msg(res.msg, {icon: 2})
}
}
})
})
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# 首页页面搭建
创建超级用户、完善admin.py;
登陆后台管理, 先添加文章表、标签表(除了评论表、点赞点踩表)等的模拟数据!
记得为已经注册的用户完善与站点表的外键关系!
在模版里拿到了文章对象,通过正反向查询,从文章表跨到站点表再跨到用户信息表,取到想要的数据!!
admin.py
from django.contrib import admin
from app01 import models
admin.site.register(models.UserInfo) # -- 用户表
admin.site.register(models.Site) # -- 站点表
admin.site.register(models.Tag) # -- 标签表
admin.site.register(models.Category) # -- 分类表
admin.site.register(models.Article) # -- 文章表
admin.site.register(models.Article2Tag) # -- 文章2标签表
admin.site.register(models.UpdandDown) # -- 点赞点踩表
admin.site.register(models.Comment ) # -- 评论表
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
views.py
from django.shortcuts import render, HttpResponse, redirect
from django.http import JsonResponse
from app01 import models
import hashlib
import random
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO, StringIO
def register(request):...
def get_random():...
def get_code(request):...
def login(request):...
def home(request):
# -- 文章多的话,可以做分页,略.
article_list = models.Article.objects.all()
return render(request, 'home.html', locals())
def logout(request):...
def set_pwd(request):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
{% load static %}
<script src="{% static 'layer-v3.5.1/layer/layer.js' %}"></script>
<title>Title</title>
<style>
a:hover{
text-decoration:none;
}
#d1 > span {
margin-left: 12px;
}
</style>
</head>
<body>
{# 导航栏 #}
<nav class="navbar navbar-default"...>
<div class="container-fluid">
<div class="row">
{# -- 左 里面放面板 #}
<div class="col-md-2">
<div class="panel panel-info">
<div class="panel-heading">
Panel title
</div>
<div class="panel-body">
Panel content
</div>
</div>
<div class="panel panel-warning"...>
<div class="panel panel-danger"...>
</div>
{# -- 中 #}
<div class="col-md-8">
{# 媒体对象 #}
<ul class="media-list">
{% for article in article_list %}
<li class="media">
<div class="media-left">
<a href="#">
{# 当前的article文章对象正向跨到站点表,再反向点表名小写到用户信息表,取到头像路径 #}
{# 前面加个/表明从根路径开始找 或者存入数据库的时前面有/ #}
{# 若图片显示不出来,检查元素,看下图片的完整路径 #}
<img class="media-object" src="/{{ article.site.userinfo.avatar }}"
width="100" alt="...">
</a>
</div>
<div class="media-body">
<h4 class="media-heading"><a href="">{{ article.title }}</a></h4>
<span style="color: gray">{{ article.desc }}</span>
</div>
</li>
<div id="d1" class="pull-right" style="margin-top: 10px">
<span>
{# 这里跳转到个人站点 可以写一个有名分组的路由 #}
<a href="/{{ article.site.userinfo.username }}">
{{ article.site.userinfo.username }}
</a>
</span>
<span>{{ article.create_time|date:'Y-m-d H:i:s' }}</span>
<span>
<span class="glyphicon glyphicon-thumbs-up"></span>
{# 若判断article.up_num值为False,则会使用过滤器,显示默认值0 #}
{{ article.up_num|default:0 }}
</span>
<span>
<span class="glyphicon glyphicon-comment"></span>
{{ article.comment_num|default:0 }}
</span>
<span>
<span class="glyphicon glyphicon-thumbs-down"></span>
{{ article.down_num|default:0 }}
</span>
</div>
<hr>
{% endfor %}
</ul>
</div>
{# -- 右 里面放面板 #}
<div class="col-md-2">
<div class="panel panel-info"...>
<div class="panel panel-warning"...>
<div class="panel panel-danger"...>
</div>
</div>
</div>
<script>
$('.edit').click(function () {...})
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# 个人站点页面搭建
我受不了啦!! 我要用Django模版的继承... (◐‿◑) !!!
# urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^register/', views.register), # -- 注册
url(r'^login/', views.login), # -- 登陆
url(r'^get_code/', views.get_code), # -- 获取验证码
url(r'^home/', views.home), # -- 首页
url(r'^logout/', views.logout), # -- 退出登陆
url(r'^set_pwd/', views.set_pwd), # -- 修改密码
# -- 写完第一时间记得测试下,看能不能到这个路由!!
url(r'^(?P<username>\w+)/', views.site), # -- 个人站点 (有名分组)
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
{% load static %}
<script src="{% static 'layer-v3.5.1/layer/layer.js' %}"></script>
<title>Title</title>
{# !!! #}
{% block css %}
{% endblock %}
</head>
<body>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/home/">BBS</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
{% if request.session.username %}
<li><a href="#">{{ request.session.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 data-toggle="modal" data-target=".bs-example-modal-sm">修改密码</a></li>
<li><a href="#">修改头像</a></li>
<li><a href="#">后台管理</a></li>
<li role="separator" class="divider"></li>
<li><a href="/logout/">退出登陆</a></li>
</ul>
</li>
{% else %}
<li><a href="/login/">登陆</a></li>
<li><a href="/register/">注册</a></li>
{% endif %}
</ul>
</div>
{# 弹出的模态框 记得添加bs-example-modal-sm 这是官网示例代码的一个bug #}
<div class="modal fade bs-example-modal-sm" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="exampleModalLabel">修改密码</h4>
</div>
<div class="modal-body">
<form action="">
<div class="form-group">
<label for="username">用户名:</label>
{# 用户名不能修改,给个默认值 #}
<input type="text" id="username" class="form-control" disabled
value="{{ request.session.username }}">
</div>
<div class="form-group">
<label for="old_pwd">旧密码:</label>
<input type="password" id="old_pwd" class="form-control">
</div>
<div class="form-group">
<label for="new_pwd">新密码:</label>
<input type="password" id="new_pwd" class="form-control">
</div>
<div class="form-group">
<label for="re_pwd">确认密码:</label>
<input type="password" id="re_pwd" class="form-control">
</div>
</form>
</div>
<div class="modal-footer">
<div class="pull-right">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary edit">保存</button>
</div>
</div>
</div>
</div>
</div>
</div>
</nav>
{% block content %}
{% endblock %}
<script>
$('.edit').click(function () {
let old_pwd = $('#old_pwd').val()
let new_pwd = $('#new_pwd').val()
let re_pwd = $('#re_pwd').val()
if (!old_pwd) {
layer.msg('请输入旧密码!')
return
}
if (!new_pwd) {
layer.msg('请输入新密码!')
return
}
if (!re_pwd) {
layer.msg('请输入确认密码!')
return
}
if (new_pwd !== re_pwd) {
layer.msg('新密码与确认密码不一致!')
return
}
$.ajax({
url: '/set_pwd/', // 为空提交到首页不合适,新开一个路由
type: 'post',
data: {
'old_pwd': old_pwd,
'new_pwd': new_pwd,
're_pwd': re_pwd,
'csrfmiddlewaretoken': '{{ csrf_token }}',
},
success: function (res) {
if (res.code == 200) {
layer.msg(res.msg, {icon: 1}, function () {
// 注册成功跳转指定页面
location.href = res.url
})
} else {
layer.msg(res.msg, {icon: 2})
}
}
})
})
</script>
{% block js %}
{% endblock %}
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# home.html
{% extends 'base.html' %}
{% block css %}
<style>
a:hover {
text-decoration: none;
}
#d1 > span {
margin-left: 12px;
}
</style>
{% endblock %}
{% block content %}
<div class="container-fluid">
<div class="row">
{# -- 左 里面放面板 #}
<div class="col-md-2">
<div class="panel panel-info">
<div class="panel-heading">
Panel title
</div>
<div class="panel-body">
Panel content
</div>
</div>
<div class="panel panel-warning" ...>
<div class="panel panel-danger" ...>
</div>
{# -- 中 #}
<div class="col-md-8">
{# 媒体对象 #}
<ul class="media-list">
{% for article in article_list %}
<li class="media">
<div class="media-left">
<a href="#">
{# 当前的article文章对象正向跨到站点表,再反向点表名小写到用户信息表,取到头像路径 #}
{# 前面加个/表明从根路径开始找 或者存入数据库的时前面有/ #}
{# 若图片显示不出来,检查元素,看下图片的完整路径 #}
<img class="media-object" src="/{{ article.site.userinfo.avatar }}" width="100">
</a>
</div>
<div class="media-body">
<h4 class="media-heading"><a href="">{{ article.title }}</a></h4>
<span style="color: gray">{{ article.desc }}</span>
</div>
</li>
<div id="d1" class="pull-right" style="margin-top: 10px">
<span>
{# 这里跳转到个人站点 可以写一个有名分组的路由 #}
<a href="/{{ article.site.userinfo.username }}">
{{ article.site.userinfo.username }}
</a>
</span>
<span>{{ article.create_time|date:'Y-m-d H:i:s' }}</span>
<span>
<span class="glyphicon glyphicon-thumbs-up"></span>
{# 若判断article.up_num值为False,则会使用过滤器,显示默认值0 #}
{{ article.up_num|default:0 }}
</span>
<span>
<span class="glyphicon glyphicon-comment"></span>
{{ article.comment_num|default:0 }}
</span>
<span>
<span class="glyphicon glyphicon-thumbs-down"></span>
{{ article.down_num|default:0 }}
</span>
</div>
<hr>
{% endfor %}
</ul>
</div>
{# -- 右 里面放面板 #}
<div class="col-md-2">
<div class="panel panel-info">
<div class="panel-heading">
Panel title
</div>
<div class="panel-body ">
Panel content
</div>
</div>
<div class="panel panel-warning" ...>
<div class="panel panel-danger" ...>
</div>
</div>
</div>
{% endblock %}
{% block js %}
{% endblock %}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# site.html
{% extends 'base.html' %}
{% block css %}
<style>
a:hover {
text-decoration: none;
}
#d1 {
margin-top: 10px;
}
#d1 > span {
margin-left: 10px;
}
</style>
{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-3">
<div class="panel panel-info">
<div class="panel-heading">
Panel title
</div>
<div class="panel-body">
Panel content
</div>
</div>
<div class="panel panel-warning" ...>
<div class="panel panel-danger" ...>
</div>
<div class="col-md-9">
<ul class="media-list">
{% for article in article_list %}
<li class="media">
<div class="media-body">
<h4 class="media-heading"><a href="">{{ article.title }}</a></h4>
<span style="color: gray">{{ article.desc }}</span>
</div>
</li>
<div style="display: flex;justify-content: flex-end;">
<div id="d1">
<span>posted @</span>
<span>{{ article.create_time|date:'Y-m-d H:i:s' }}</span>
<span>{{ article.site.userinfo.username }}</span>
<span>点赞数({{ article.up_num|default:0 }})</span>
<span>评论数({{ article.comment_num|default:0 }})</span>
<span>点踩数({{ article.down_num|default:0 }})</span>
</div>
</div>
<hr>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endblock %}
{% block js %}
{% endblock %}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# error.html
404页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="text-align: center">
<img src="/static/img/very_sorry.png" alt="">
</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# views.py
from django.shortcuts import render, HttpResponse, redirect
from django.http import JsonResponse
from app01 import models
import hashlib
import random
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO, StringIO
def register(request):...
def get_random():...
def get_code(request):...
def login(request):...
def home(request):...
def logout(request):...
def set_pwd(request):...
def site(request, site_name):
# 需求:过滤出当前站点的所有文章!需要先判断,若该站点不存在,跳转404页面!
site_obj = models.Site.objects.filter(site_name=site_name).first()
if not site_obj:
return render(request,'error.html')
# -- 方式一:用对象来跨
article_list = site_obj.article_set.all()
# -- 方式二: 用字段来跨 这行代码也可以达到同样的效果!!
# article_list = models.Article.objects.filter(site__site_name=site_name).all()
# -- 若有名分组取到的用户名.(不过多考虑合理性,因为用户名可能会重复)
# article_list = models.Article.objects.filter(site__userinfo__username=username).all()
return render(request, 'site.html', locals())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43