day73 bbs项目☞基本功能实现
一、登录功能
views.py
0难度,都是基本操作,要熟悉auth模块的使用
# 登录功能
def login(request):
# 1 获取前端传来的数据
if request.method=='POST':
back_dic = {'code':0,'msg':''}
username = request.POST.get('username')
password = request.POST.get('password')
code = request.POST.get('code')
# 2 验证验证码是否正确
if code == request.session.get('code'):
obj = auth.authenticate(request,username=username,password=password)
# 3 验证用户是否正确
if obj:
auth.login(request,obj)
back_dic['code'] = 1000
# 登录成功后跳转到home页面
back_dic['url'] = '/home/'
# 错误信息msg在前端要渲染到错误标签位置
else:
back_dic['msg'] = '账号或密码错误'
else:
back_dic['msg'] = '验证码错误'
return JsonResponse(back_dic)
# 4 针对不同的情况返回不同的json数据(注意:通常ajax请求都需要一个字典去执行不同情况的结果)
return render(request,'login.html')
二、首页搭建
home.html
- 对页面布局的使用
- 熟练掌握前端组件的拷贝和应用
- ajax请求基本操作
- 静态文件暴露(展示头像)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-inverse">
<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">BBS</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">BBS</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>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
{# 判断用户是否登录#}
<ul class="nav navbar-nav navbar-right">
{% if request.user.is_authenticated %}
<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="#" data-toggle="modal" data-target=".bs-example-modal-lg">修改密码</a></li>
<li><a href="/logout/">退出登录</a></li>
<li><a href="#">修改头像</a></li>
<li><a href="#">后台管理</a></li>
</ul>
</li>
{% else %}
<li><a href="/login/">登录</a></li>
<li><a href="/register/">注册</a></li>
{% endif %}
</ul>
<div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<h1 class="text-center">修改密码</h1>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="form-group">
<label for="">用户名:</label>
<input type="text" class="form-control" disabled value="{{ request.user }}">
</div>
<div class="form-group">
<p>原密码:<input type="password" class="form-control" id="old_password"></p>
</div>
<p>新密码:<input type="password" class="form-control" id="new_password"></p>
<p>确认密码<input type="password" class="form-control" id="password_again"></p>
</div>
</div>
<div class="modal-footer">
<span style="color: red" id="error"></span>
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" id="mybtn">提交</button>
</div>
</div>
</div>
</div>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<div class="panel panel-default">
<div class="panel-heading">性感荷官</div>
<div class="panel-body">
在线发牌
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">知名女优</h3>
</div>
<div class="panel-body">
等你来战
</div>
</div>
</div>
<div class="col-md-8">
{% for article in article_list %}
<ul class="media-list">
<li class="media">
<h3 class="media-heading"><a>{{ article.title }}</a></h3>
<div class="media-left">
<a href="#">
<img class="media-object" src="/media/{{ article.blog.userinfo.avatar }}" height="80px">
</a>
</div>
<div class="media-body">
{{ article.desc }}
</div>
<br>
<div style="color: #a9a9a9">
<span><a href="/{{ article.blog.userinfo.username }}">{{ article.blog.userinfo.username }}  </a></span>
<span>发布于 </span>
<span>{{ article.create_time|date:'Y年m月d日' }}  </span>
<span><span class="glyphicon glyphicon-comment"></span> 评论({{ article.comment_num }})</span>
<span><span class="glyphicon glyphicon-thumbs-up"></span> 点赞({{ article.up_num }})</span>
</div>
</li>
</ul>
<hr>
{% endfor %}
</div>
<div class="col-md-2">
<div class="panel panel-default">
<div class="panel-heading">性感荷官</div>
<div class="panel-body">
在线发牌
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">知名女优</h3>
</div>
<div class="panel-body">
等你来战
</div>
</div>
</div>
</div>
</div>
<script>
$('#mybtn').click(function () {
$.ajax({
url:'/set_password',
type:'post',
data:{
'old_password':$('#old_password').val(),
'new_password':$('#new_password').val(),
'password_again':$('#password_again').val(),
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success:function (args) {
if(args.code == 1000){
window.location.href = args.url
}else {
$('#error').text(args.msg)
}
}
})
})
</script>
</body>
</html>
settings.py
# 用户上传的文件应该存储到专门的文件夹,类比static
# 但是此处只是配置了路径,还没有在url开放接口
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
url.py
from django.views.static import serve
from app01 import settings
# 在前端开放接口后才能直接访问对应资源的文件
url(r'^mdedia/(?P<path>.*)',serve,{'document_root':settings.MEDIA_ROOT})
三、admin后台管理
'''
django有一个可视化后台管理界面,对数据进行增删改查
先要在admin.py注册你要操作的表
'''
from django.contrib import admin
from app01 import models
# Register your models here.
admin.site.register(models.UserInfo)
admin.site.register(models.Tag)
admin.site.register(models.Blog)
admin.site.register(models.Article)
admin.site.register(models.Article2Tag)
admin.site.register(models.Category)
admin.site.register(models.Comment)
admin.site.register(models.UpAndDowm)
'''
然后用有管理员权限的用户登录admin,每个表有对应的增删改查功能
这里要特别注意表关系,不能瞎绑定
注意在models.py中设计表的时候有一些参数可以帮助我们更清晰的观察表
'''
# verbose_name 可以在管理界面代替title展示给用户
title = models.CharField(max_length=32,verbose_name='文章标题')
# null=True 是告诉数据库可以为空,blank=True 是告诉管理后端可以为空
phone = models.BigIntegerField(null=True,blank=True)
# 修改表名
class Meta:
#verbose_name = '用户表' # 这种方式默认后面加s
verbose_name_plural = '用户表'
# 代替数据对象展示在前端
def __str__(self):
return self.username
四、图片防盗链
可以避免别的网站直接通过本网站的url访问本网站资源
简单的防盗:
如果是本网站发送的请求就正常访问,不是就拒绝访问
在请求头中有一个参数专门用来存放请求来源
Referer:http://127.0.0.1:8000/xxx/
如何避免:
直接修改请求头
直接爬取对方网址内的资源
五、个人站点展示
- 展示的时候需要熟练掌握跨表查询应用(聚合函数,分组查询)
- 对于不同筛选条件的url(有名分组)
- 日期类型特定筛选(TruncMouth)
views.py
def site(request,username,**kwargs):
user_obj = models.UserInfo.objects.filter(username=username).first()
if not user_obj:
return render(request,'error.html')
blog = user_obj.blog
article_list = models.Article.objects.filter(blog=blog)
print(kwargs)
if kwargs:
condition = kwargs.get('condition')
param = kwargs.get('param')
print(condition,param)
if condition == 'category':
article_list = article_list.filter(category_id = param)
elif condition == 'tag':
article_list = article_list.filter(tag__id = param)
else:
year,month = param.split('-')
article_list = article_list.filter(create_time__year =year,create_time__month=month)
# 1 查询当前用户所有的分类及分类下的文章数
category_list = models.Category.objects.filter(blog=blog).annotate(count_num = Count('article__pk')).values_list('name','count_num','pk')
# 2 查询当前用户下所有的标签下的文章数
tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num = Count('article__pk')).values_list('name','count_num','pk')
# 3 以创建日期为分类
date_list = models.Article.objects.filter(blog=blog).annotate(mouth = TruncMonth('create_time')).values('mouth').annotate(count_num=Count('pk')).values_list('mouth','count_num')
return render(request,'site.html',locals())
site.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-inverse">
<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">BBS</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">{{ blog.site_name }}</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>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
{# 判断用户是否登录#}
<ul class="nav navbar-nav navbar-right">
{% if request.user.is_authenticated %}
<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="#" data-toggle="modal" data-target=".bs-example-modal-lg">修改密码</a></li>
<li><a href="/logout/">退出登录</a></li>
<li><a href="#">修改头像</a></li>
<li><a href="#">后台管理</a></li>
</ul>
</li>
{% else %}
<li><a href="/login/">登录</a></li>
<li><a href="/register/">注册</a></li>
{% endif %}
</ul>
<div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<h1 class="text-center">修改密码</h1>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="form-group">
<label for="">用户名:</label>
<input type="text" class="form-control" disabled value="{{ request.user }}">
</div>
<div class="form-group">
<p>原密码:<input type="password" class="form-control" id="old_password"></p>
</div>
<p>新密码:<input type="password" class="form-control" id="new_password"></p>
<p>确认密码<input type="password" class="form-control" id="password_again"></p>
</div>
</div>
<div class="modal-footer">
<span style="color: red" id="error"></span>
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" id="mybtn">提交</button>
</div>
</div>
</div>
</div>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<div class="panel panel-default">
<div class="panel-heading">文章标签</div>
<div class="panel-body">
{% for tag in tag_list %}
<p><a href="/{{ username }}/tag/{{ tag.2 }}">{{ tag.0 }} ({{ tag.1 }})</a></p>
{% endfor %}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title " >文章分类</h3>
</div>
<div class="panel-body">
{% for category in category_list %}
<p><a href="/{{ username }}/category/{{ category.2 }}">{{ category.0 }} ({{ category.1 }})</a></p>
{% endfor %}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title " >日期</h3>
</div>
<div class="panel-body">
{% for date in date_list %}
<p><a href="/{{ username }}/archive/{{ date.0|date:'Y-m' }}">{{ date.0 }} ({{ date.1 }})</a></p>
{% endfor %}
</div>
</div>
</div>
<div class="col-md-8">
{% for article in article_list %}
<ul class="media-list">
<li class="media">
<h3 class="media-heading"><a>{{ article.title }}</a></h3>
<div class="media-left">
<a href="#">
<img class="media-object" src="/media/{{ article.blog.userinfo.avatar }}" height="80px">
</a>
</div>
<div class="media-body">
{{ article.desc }}
</div>
<br>
<div style="color: #a9a9a9">
<span>posted </span>
<span>@ </span>
<span>{{ article.create_time|date:'Y年m月d日' }} </span>
<span><span class="glyphicon glyphicon-comment"></span> 评论({{ article.comment_num }})</span>
<span><span class="glyphicon glyphicon-thumbs-up"></span> 点赞({{ article.up_num }})</span>
<span><a href="#">编辑</a></span>
</div>
</li>
</ul>
<hr>
{% endfor %}
</div>
</div>
</div>
</body>
</html>
urls.py
url(r'^(?P<username>\w+)/$',views.site),
url(r'^(?P<username>\w+)/(?P<condition>category|tag|archive)/(?P<param>.*)/',views.site)
day73 bbs项目☞基本功能实现的更多相关文章
- BBS项目分布搭建三(个人站点时间归档补充,实现侧边栏跳转、无线级分类、实现文章详情页展示功能)
BBS项目分布搭建三(个人站点时间归档补充,) 1. 个人站点时间归档 """ settings.py设置最好更改以下: LANGUAGE_CODE = 'zh-hans ...
- BBS项目分布搭建四(点赞点踩及评论功能准备)
BBS项目分布搭建四(点赞点踩及评论功能) 1. 点赞点踩样式准备 # 在base.html文件中 head标签内 添加css模块: {% block css %} {% endblock %} # ...
- BBS项目分布搭建五(评论相关功能实现)
BBS项目分布搭建五(评论相关) 1. 根评论逻辑实现 # 在models.py文件中 修改: # 7. 评论表 parent = models.ForeignKey(to='self', null= ...
- BBS项目补充知识(后台文章展示功能)
BBS项目补充知识 1. 开放 media 文件路径 # 以用户注册页面为例 用户头像文件我们默认时保存在 根路径下的static下的img文件夹 但也可以单独放置在指定路径下 # 根路径下创建 me ...
- BBS项目详解(forms快速创建登陆页面,登陆验证、通过阅读器进行头像上传的预览、内存管理器)
BBS项目涉及的知识点 django中知识点 钩子函数(局部钩子和全局钩子) 1.局部钩子就是用来做合法性校验,比如用户名有没有被使用等 2.全局的就是用来做对比校验,比如两次输入的密码是否一致 3. ...
- auth复习和BBS项目的登录(1)
auth复习 auth组件 验证:authenticate(request,username='andy',password='123) 登录:login(request,user) 注销:login ...
- python 自动化之路 day 20 Django进阶/BBS项目【一】
一.django进阶 1.django orm 增删改查 1.1.创建表: 1 2 3 >>> from blog.models import Blog >>> b ...
- BBS项目-01
目录 BBS项目 BBS开发流程: BBS表格创建: BBS项目 BBS开发流程: BBS项目: 开发流程: 需求分析 草拟一些项目的大致技术点和流程 架构设计 架构师(框架 语言 数据库 缓存数据库 ...
- 小福bbs—项目系统设计与数据库设计
这个作业属于哪个课程 班级链接 这个作业要求在哪里 作业要求的链接 团队名称 小福bbs 这个作业的目标 实现对校园论坛软件的制作,使其能够发布帖子,查看信息等 作业的正文 小福bbs--项目需求分析 ...
随机推荐
- 移动UI系列 - 简单地使用半衰期算法来预测手势的滑动方向与速度
前言 有一个问题, 给定一个物体的运动轨迹, 包含时间和坐标的数组, 如何使用这个数据来预测物体未来的运动走势?? 本文提供了一个很简单的方式去实现这个算法. 效果够用, 又简单, 有一定的准确程度. ...
- 解Bug之路-记一次JVM堆外内存泄露Bug的查找
解Bug之路-记一次JVM堆外内存泄露Bug的查找 前言 JVM的堆外内存泄露的定位一直是个比较棘手的问题.此次的Bug查找从堆内内存的泄露反推出堆外内存,同时对物理内存的使用做了定量的分析,从而实锤 ...
- 君荣 TS--8200 消费机显示说明
Err 001——不在消费时段内Err 002——非本系统卡Err 003——余额不足Err 004——级别未开放Err 005——卡已挂失Err 006——有效期未生效Err 007——已过有效期 ...
- 怒肝俩月,新鲜出炉史上最有趣的Java小白手册,第一版,每个 Java 初学者都应该收藏
这么说吧,在我眼里,Java 就是最流行的编程语言,没有之一(PHP 往一边站).不仅岗位多,容易找到工作,关键是薪资水平也到位,不学 Java 亏得慌,对吧? 那可能零基础学编程的小伙伴就会头疼了, ...
- LR脚本信息函数-lr_user_data_point
Loadrunner中lr_user_data_point.lr_user_data_point_instance两个函数可以用来记录一条自定义的Vuser运行数据,并将其输出到测试结果中,最后可以通 ...
- node-sass问题
cnpm install node-sass@latest 或者 所以用npm install -g cnpm --registry=https://registry.npm.taobao.org , ...
- SpringBoot整合Hibernate Validator实现参数验证功能
在前后端分离的开发模式中,后端对前端传入的参数的校验成了必不可少的一个环节.但是在多参数的情况下,在controller层加上参数验证,会显得特别臃肿,并且会有许多的重复代码.这里可以引用Hibern ...
- Nginx配置rewrite过程介绍
创建rewrite语句 vi conf/vhost/www.abc.com.conf #vi编辑虚拟主机配置文件 文件内容 server { listen 80; server_name abc.co ...
- Java 源码刨析 - 线程的状态有哪些?它是如何工作的?
线程(Thread)是并发编程的基础,也是程序执行的最小单元,它依托进程而存在. 一个进程中可以包含多个线程,多线程可以共享一块内存空间和一组系统资源,因此线程之间的切换更加节省资源.更加轻量化,也因 ...
- WeChair项目Beta冲刺(10/10)
团队项目进行情况 1.昨日进展 Beta冲刺第十天 昨日进展: 项目完工 2.今日安排 对小程序进行测试,同时对项目进行总结,并整理博客材料等 3.燃尽图 4.展示Git当日代码记录 详情 ...