BBS+ BLOG系统(仿博客园)
一、基本要求
作业题目:开发BBS+BLOG系统
作业需求:
1 基于ajax和用户认证组件实现登录验证 2 基于ajax和form组件实现注册功能 3 系统首页文章列表的渲染 4 个人站点页面设计5 文章详细页的继承6 点赞与踩灭7 评论功能8 富文本编辑器的使用9 防止xss攻击
评论处、上传文章处都要防止xss攻击--凡是向网站输入内容的都要防止
博客系统开发:
1.注册,登录,首页 2.个人站点,分组:(分类,标签,归档) 3.文章详细页 4.点赞,踩灭 5.评论楼,评论树 6.后台管理,发布文章,文件上传 7.BeautifulSoup 8.日志
----
演示内容,
1、注册输入为空,输入已注册过的信息提交
2、登录为空、输入错误提交
3、展示首页---注销--重新输入---
4、个人站点--展示--进入文章详情页
5、评论--点赞---防xss攻击评论
6、后台管理--先正常文字图片---在防xss攻击编辑
一、项目流程:
项目流程:1 搞清楚需求(产品经理)(1) 基于用户认证组件和Ajax实现登录验证(图片验证码)(2) 基于forms组件和Ajax实现注册功能(3) 设计系统首页(文章列表渲染)(4) 设计个人站点页面---跨表查询,分组查询(5) 文章详情页(6) 实现文章点赞功能(7) 实现文章的评论---文章的评论---评论的评论(8) 富文本编辑框 和 防止xss攻击(防止别人提交js代码)2 设计表结构3 按着每一个功能分别进行开发4 功能测试5 项目部署上线
二、功能实现
参考:
https://www.cnblogs.com/venicid/p/9446064.html
https://www.cnblogs.com/alice-bj/p/9160388.html
1、注册、登录、注销、出错页面
2) 注册/register/3) 登录/login//get_validCode/ # 验证码4) 注销/logout/5) 404页面not_found.html
基于用户认证组件和Ajax实现登录验证(图片验证码)
基于forms组件和ajax实现注册功能
--------
引入Bootstrap<h3 class="text-primary text-center">注册页面</h3> <form> <div class="form-group "> <label for="username">username</label><input type="text" class="form-control " placeholder="username" id="username"></div></form>
2、主页、个人站点,文章详情页
0) 主页 /index/ 1) 个人站点页面(分类、标签、归档)/alex/2) 文章详情页(分类、标签、归档)/alex/articles/4/digg # 点赞/comment # 评论/get_comment_tree # 评论树展示4)media开放目录/media
0 博客首页布局
登录状态和未登陆状态的两种区别
导航栏设计---Bootstrap--导航条
主页左右栏设计补充
知识点:1.bootstrap搭建页面2.导航条登录: username / 注销未登录: 登录 / 注册3.for循环{% for article in article_list %}{% endfor %}
1 个人站点
ORM跨表与分组查询
知识点:1.文章列表,分类列表,标签列表,日期归档列表文章列表: 分类列表: 标签列表: 日期归档列表: 2.模板继承{% extends 'base.html' %}{% block content %}{% endblock content%}}3.自定义标签/blog/templatetags/my_tag.py@register.inclusion_tag('')def get_menu(username):...return {} # 去渲染 4.分组查询 .annotate() / extra()应用多表分组tag_list = Tag.objects.filter(blog=blog).annotate(count = Count('article')).values_list('title', 'count')单表分组 / DATE_FORMAT() / extra()date_list = Article.objects.filter(user=user).extra(select={"create_ym": "DATE_FORMAT(create_time,'%%Y-%%m')"}).values('create_ym').annotate(c = Count('nid')).values_list('create_ym', 'c')5. 时间、区域配置TIME_ZONE = 'Asia/Shanghai'USE_TZ = False
2、文章详情页的设计
知识点:1.模板继承article = Article.objects.filter(pk=article_id).first(){% extends 'base.html' %}{% block content %}...{{ article.articledetail.content|safe }}{% endblock content %}
3、点赞、踩灭
----------------
知识点:1.ajax的postvar csrfmiddlewaretoken = $('input[name="csrfmiddlewaretoken"]').val();2.事务try: # article_id 与 user_id 联合唯一 所有使用 try ... with transaction.atomic():ArticleUpDown.objects.create(is_up=is_up, article_id=article_id, user_id=user_id)...Article.objects.filter(pk=article_id).update(up_count=F('up_count')+1)except Exception as e:...3.F查询:Article.objects.filter(pk=article_id).update(up_count=F('up_count')+1)
4、评论楼、评论树
ajax显示评论
1.提交根评论 2.显示根评论--- render显示--- ajax显示 3.提交子评论 4.显示子评论--- render显示--- ajax显示 评论楼 评论树 1.ajax提交评论post (csrfmiddlewaretoken)pid = "" 根评论pid = value 子评论2.回复事件@alexval ="@" + $(this).attr('username')+ '\n';3.事务with transaction.atomic():...多个orm sql操作!4.F查询,更新Article.objects.filter(pk=article_id).update(comment_count=F("comment_count")+1)评论树:5.js匿名函数(function(){})()6.ajax get方式获取comment_list$.each(comment_list,function(index,comment)){...s = '...'if(pid){ //子评论$('#'+pid).append(s)}else{ //根评论$('.comment_tree').append(s)}}7.JsonResponse() 返回 non-dict objects 需要 safe=Falsedef get_comment_tree(request, article_id):ret = list(Comment.objects.filter(article_id=article_id).values('pk', 'content', 'parent_comment_id', 'user__username').order_by('nid'))return JsonResponse(ret, safe=False)
5、后台管理、KindEditor、BeautifulSoup
/cn_backend # 主页/cn_backend/add_article/ # 添加文章/cn_backend/edit_article/4 # 编辑文章/delete # 删除
知识点:1.新建APP(backend)settings:INSTALLED_APPS = [..., 'backend.apps.BackendConfig',]2.url分配re_path(r'backend/', include(('backend.urls', 'backend'))),3.认证装饰器@login_requiredsettings:LOGIN_URL = '/login/'4.static配置STATIC_URL = '/static/'STATICFILES_DIRS = [os.path.join(BASE_DIR, 'blog', 'static'),os.path.join(BASE_DIR, 'backend', 'static'),]5.编辑器(KindEditor)<textarea name="article_con" id="article_box" cols="30" rows="10"></textarea><script src="/static/kindeditor/kindeditor-all.js"></script>KindEditor.ready(function (k) {window.editor = k.create('#article_box', {......uploadJson: 'upload_img/',extraFileUploadParams: {"csrfmiddlewaretoken":$('input[name="csrfmiddlewaretoken"]').val()},filePostName: 'img'})})6.文件上传用户文件存在 /media/article_imgs/...media_path = settings.MEDIA_ROOTpath = os.path.join(media_path, 'article_imgs', img_obj.name)返回jsonimg_obj = request.FILES.get('img')res = {"url": "/media/article_imgs/"+img_obj.name,"error": 0}return HttpResponse(json.dumps(res))7.发布文章防止XSS攻击 BeautifulSoup,对网页,解析数据article_con = request.POST.get('article_con')soup = BeautifulSoup(article_con, 'html.parser')# 过滤script, 删除了所有的script标签for tag in soup.find_all():if tag.name == 'script':tag.decompose()# soup.prettify() == str(soup)return redirect(reverse('backend:index'))
三、所用技术概述
1、验证用户是否登录:用户认证组件实质:session会话跟踪技术 from django.contrib import auth 通过中间件auth_middleware.py,采用白名单,对url进行控制,替代装饰器@login_requierd,否则每一个函数都有要加装饰器。 from django.utils.deprecation import MiddlewareMixin 2、验证字段:表单forms组件对每个数据库中的字段进行校验,返回error from django import forms 3、自定义分页器分页器pagination.py 解耦 from blog.utils.pagination import MyPaginator # 分页器 4、记录日志logsettings配置文件,终端打印sql语句 mylog.py 日志文件,解耦,终端打印并在log文件记录用户操作 import logging 5、模板继承{% extends 'base.html' %}{% block site-header %}{% endblock %} 6、ORM表关系一对一(user blog) 一对多(user article) 多对多(article tag) 7、注意点:1) 时区: settings.py配置# TIME_ZONE = 'UTC'TIME_ZONE = 'Asia/Shanghai'USE_TZ = False2) 静态文件目录 STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static') ] 8、连接mysql数据库settings配置 # 连接mysql数据库 DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'cnblog', # 要连接的数据库,连接前需要创建好'USER': 'root', # 连接数据库的用户名'PASSWORD': 'root', # 连接数据库的密码'HOST': '127.0.0.1', # 连接主机,默认本级'PORT': 3306, # 端口 默认3306 } } 9、评论后发送邮件settings文件配置 # 发送邮件 EMAIL_USE_SSL = True # EMIAL_HOST = 'smtp.exmail.qq.com' # 如果是163 改成smtp.163.com EMAIL_HOST = 'smtp.qq.com' # 如果是 163 改成 smtp.163.com EMAIL_PORT = 465 EMAIL_HOST_USER = '719633333@qq.com' # 账号 EMAIL_HOST_PASSWORD = 'or333333ndzubdie' # qq邮箱的授权码而不是密码 DEFAULT_FROM_EMAIL = EMAIL_HOST_USERviews视图 from django.core.mail import send_mail # 发送邮件# 多进程发送邮件 t = threading.Thread(target=send_mail, args=("你的文章【%s】新增了一条评论内容" % article_obj.title,content,settings.EMAIL_HOST_USER,[request.user.email],))t.start() 10、验证码PIL模块生成验证码 from PIL import Image, ImageDraw, ImageFont 11、自定义tag标签from django import template register = template.Library() @register.inclusion_tag("blog/classification.html") def get_classification_style(username): 12、数据库事务操作from django.db import transaction # 事务操作 13、富文本编辑框KindEditor 14、防止xss攻击from bs4 import BeautifulSoup
其他
xss攻击 {{ article_obj.content|safe }} safe是让所用提交都通过
我们在提交阶段认为的剔除非法的标签
标签页的知识:
data-toggle="tab"——指明标签项具有切换响应功能; .tab-content——包裹标签页的所有内容部分; .tab-pane——包裹对应标签项的内容部分; .fade——设置标签项切换时有淡入淡出的效果; .in——设置标签页第一项淡入的初始化效果; .active——设置标签页以及对应标签项的内容处于激活状态;
----
![](/assets/blank.gif)
![](/assets/blank.gif)
<!-- Nav tabs Bootstrap 中的--选项卡--><ul class="nav nav-tabs" role="tablist"><li role="presentation" class="active"><a href="#home" aria-controls="home" role="tab"data-toggle="tab">文章</a></li><li role="presentation"><a href="#profile" aria-controls="profile" role="tab"data-toggle="tab">日记</a></li><li role="presentation"><a href="#messages" aria-controls="messages" role="tab" data-toggle="tab">随笔</a></li><li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">相册</a></li></ul><!-- Tab panes --><div class="tab-content"><div role="tabpanel" class="tab-pane active" id="home">{% block content %}{% endblock %}</div><div role="tabpanel" class="tab-pane" id="profile"><img src="/static/img/meinv2.jpg" alt=""><img src="/static/img/meinv3.jpg" alt=""><img class="pull-right" src="/static/img/meinv.jpg" alt=""></div><div role="tabpanel" class="tab-pane" id="messages"><img width="180" height="180" src="/static/img/hashiqi2.jpg" alt=""><img width="180" height="180" src="/static/img/dogg4.jpg" alt=""><img width="180" height="180" src="/static/img/linhaifeng.jpg" alt=""><br><img width="180" height="180" src="/static/img/dogg3.jpeg" alt=""><img width="180" height="180" src="/static/img/dogge2.jpg" alt=""><img width="180" height="180" src="/static/img/dogg5.jpg" alt=""></div><div role="tabpanel" class="tab-pane" id="settings"></div>
View Code
防止xxs攻击
<script>alert(1111)</script>
数据库(pycharm连接mysql数据库) models.py注册 /reg/上传头像 request.FILES.get('avatar')登录 /login/随机验证码 /get_valid_img/首页 /index/个人站点分类,标签,归档 /blog/egon/文章详细页 /blog/egon/articles/2/点赞,踩灭 /blog/poll/ajax的post 事务评论楼,评论树 /blog/comment/根评论,子评论render显示,ajax显示后台管理,发布文章 /backend/index/新建APP认证装饰器编辑器(KindEditor)文件上传 /media/article_imgs/...防止XSS攻击BeautifulSoup
转载于:https://www.cnblogs.com/foremostxl/p/10017917.html
BBS+ BLOG系统(仿博客园)相关推荐
- BBS(仿博客园系统)项目03(主页搭建、个人站点搭建(侧边栏分类展示、标签展示、日期归档)、文章详情页相关功能实现)...
摘要: 主页面的搭建(导航条下面的区域) 个人站点 侧边栏分类展示 侧边栏标签展示 侧边栏日期归档 文章详情页 文章内容 文章点赞点踩 文章评论 一.主页面home.html的搭建(进一步完善) ho ...
- 博客园php教程,PHP仿博客园,个人博客(1)_PHP教程
本人本科学历,自学PHP大半年多了,断断续续地,但是最终还是坚定了我的想法,将PHP继续下去,所以写这个PHP的博客是为了找个稳定的 PHP工作,不求工资多高,但求一收留之地.我能看懂大部分英语文档, ...
- python3进阶开发-第一个仿博客园的项目(1)
首先我们要设计一下表结构: UserInfo(用户信息表) -------->一对一 ----------->Blog(博客信息表) UserInfo(用户信息表) -------- ...
- 仿博客园个人博客(3)基本完成
唠叨几句: 前段时间找了家公司上班,也算是真正跨入了计算机行业了,可惜地是我们这城市太小,没什么PHP工作机会,少数地几家都是做网络营销型的,我几乎相当于美工!可我不会啊,但是他们招聘条件上说了: 要 ...
- [Tool] 仿博客园插入代码的 WLW 插件
一 插件相关效果图展示 插件效果图: 在 Windows Live Writer 中的效果如图: [1] [2] [3] 对应的插入代码在博客中的效果如下: [1] public static vo ...
- BBS(仿博客园系统)项目01(项目分析、表结构设计、注册功能实现)
摘要: 需求分析 表结构设计 注册功能实现 一.需求分析: 项目需求(产品经理.架构师.开发组组长与客户谈该项目相关要求) 项目设计 (架构师需要思考:框架选择,数据库选择,主要功能模块,报价:包括工 ...
- python3-开发进阶-仿博客园项目setting.py的文件的配置,admin,forms(2)
前面我们先分析了一下,做这个项目需要的几张表,今天我们从配置文件开始一步一步去解释这么的原因 首先先来看setting.py文件: """ Django settings ...
- linux7单用户模式重启,Centos7 进入单用户模式,修复系统 - jsjrj01 - 博客园
一.开机时进入如下界面,(按下方向键盘,阻止系统自动继续) 按e键出现下面界面 按方向键下,定位到最后,找到"ro"一行,ro的意思是read only,将"ro&quo ...
- 博客搬家了--这次搬进自己家的了,不过博客园的会定时更新!新家地址: http://blog.woshimaijia.com/...
博客搬家了--这次搬进自己家的了,不过博客园的会定时更新! 新家地址: http://blog.woshimaijia.com/ 博客园的博客很稳定,也是我很喜欢的地方 这里的文章我也会陆续更新的.. ...
最新文章
- 无线覆盖带机量比较大的型号推荐
- maven依赖decoder_引入依赖maven打包报错
- IOS-UITextField-改变光标颜色
- c++ vector方法
- javascript权威指南——笔记(第十章:正则)
- oracle 连接greenplum,Oracle通过DBLINK访问GreenPlum
- 蚂蚁金服OceanBase挑战TPCC | TPC-C基准测试之存储优化
- 太形象了!什么是边缘计算?最有趣的解释没有之一!
- googlemap 两点间平滑移动_Salomon萨洛蒙徒步登山鞋实测,一双在山林与城市间探索的户外鞋...
- OpenCV_(Laplacian Transform to find the edges)图像拉普拉斯变换查找边缘 图像识别
- python读取excel合并单元_python 读写excel (合并单元格)
- Django 前戏
- 国考银保监会计算机类笔试,银保监会(计算机类)笔试资料(含2018-2019真题).zip...
- Android11裁剪,Andorid 11调用系统裁剪
- 业务流程驱动的数字化转型,中小微企业开启转型的最简单方法论
- bat脚本设置系统环境变量即时生效
- Cython优化简介
- 树莓派配置记录——aria2
- Google 后 Hadoop 时代的新 “三驾马车” -- Caffeine(搜索)、Pregel(图计算)、Dremel(查询)
- java 调用博思得条码打印机