Frank的学习之路

Day_23_总结_BBS实现

今日内容:

         -首页,文章的展示

         -个人站点(不同人不同样式),标签、分类、归档过滤

         -文章详情页(母版继承,文章样式)

         -点赞、点踩

         -评论的展示和提交

                   -子评论

         -后台管理文章展示

         -文章的发布(富文本编辑器的使用)

 

1.首页,文章的展示:

         -添加文章:用admin组件

                   -admin.py中注册表模型,创建超级管理员账号,注册数据库表

                  -页面渲染:for

                   -判断用户是否登录

        

                   -blog-admin.py

                   from blog import models

                   # Register your models here.

                   admin.site.register(models.UserInfo)

                   admin.site.register(models.Blog)

                   admin.site.register(models.Article)

                   admin.site.register(models.Category)

                   admin.site.register(models.Tag)

                   admin.site.register(models.Article2Tag)

                   admin.site.register(models.ArticleUpDown)

步骤:

         (1).创建index.html ,引入bootstrap

         (2).使用admin账号登录,Article表中创建文章,注意user表中和字段和博客主页关联

         (3).index.html通过for循环取出文章,通过bs的多媒体控件,配置图片和文章简介

         (4).通过span配置评论人,发布时间和评论数

         (5).配置动态文件路径media,需要开口

         ----------------------------------------------------------------------------

         (6).设置访问根目录跳转index页面,根据地址访问的人,切换对应的站点(根据用户,生产环境根据博客站点)

         (7).根据地址访问的人切换对应的样式(用户需要关联个人博客)

         ----------------------------------------------------------------------------

         (8).当前站点下所有的分类,对应的文章数(通过双下划线查询)

         (9).查询当前站点下所有的标签,对应的文章数(通过双下划线查询)

         ----------------------------------------------------------------------------

         (10).设置文章创建的时间和存储数据库时间(settings配置)

         (11).配置个人博客每个月的文章数(使用时间截断TruncMonth

         ----------------------------------------------------------------------------

         (12).通过a标签链接分类,标签,时间过滤文章

        

2.-个人站点

         -个人站点路由涉及:url(r'(?P<username>\w+)/', views.home_site),

         -几个分组查询:查询分类下文章数,标签下文章数,年月下文章数

        

3.文章详情页

         使用母版继承,配置母版base.html,home_site.htmlarticl.html继承母版

         (13).配置详情页

        

        

访问根目录跳转index页面,任意路径跳转404

-BBS_new-urls.py

    #访问根目录跳转index

    url(r'^$', views.index),

    url(r'', views.error),

 

 

(2).创建超级管理员账号

方法一:        

         pychar运行Tools-Run manage.py Task ,然后运行createsuperuser

方法二:

         Terminal下运行python manage.py createsuperuser

 

(4).统计文章(Article)的评论(Comment),反向查询    

基于对象的表查询

正向

一对一:按字段

一对多,多对多,按字段

总结:正向查询安装字段

 

反向

一对一:按表名小写

一对多,多对多:安表名小写_set

总结:按表名小写,如果多_set,如果是一个就是表名小写

 

基于双下划线的跨表查询

正向查询:按字段

反向查询:按表名小写

 

(5).配置动态文件路径media,需要开口

-settings.py

         #与用户上传的位置有关

         #默认上传的文件,都会放到这个文件夹下

         MEDIA_ROOT=os.path.join(BASE_DIR,"media")

         MEDIA_URL="/media/"

        

-BBS_new-urls.py

from django.views.static import serve

from BBS_new import settings

#开一个media的路径

    url(r'^media/(?P<path>.*)', serve,{'document_root':settings.MEDIA_ROOT}),

        

(6).设置跳转

-BBS_new-urls.py

    url(r'(?P<username>\w+)/', views.home_site),

    #访问根目录跳转index

    url(r'^$', views.index),

    url(r'', views.error),

        

-templates-home_site.html

<link rel="stylesheet" href="/static/css/{{ user.blog.theme }}">

 

(8).配置分类统计文章数

-blog-views.py

ca_num = models.Category.objects.all().filter(blog=blog).annotate(category_count=Count('article__title')).values_list('title', 'category_count','pk')

-templates-home_site.html

         {% for foo in ca_num %}

                   <p><a href="">{{ foo.0 }}({{ foo.1 }})</a></p>

         {% endfor %}

 

(9).配置标签统计文章数

-blog-views.py

tag_num=models.Tag.objects.all().filter(blog=blog).values('nid').annotate(tag_count=Count('article__title')).values_list('title','tag_count','pk')

 

-templates-home_site.html

         {% for foo in tag_num %}

                   <p><a href="">{{ foo.0 }}({{ foo.1 }})</a></p>

         {% endfor %}

        

(9).配置时间

-BBS_new-settings.py

#使用上海的时间

TIME_ZONE = 'Asia/Shanghai'

#说明不用utc的时间,用当地的时间

USE_TZ = False

 

(10).配置个人博客每月统计文章数

-blog-views.py

    #查询每个月发表文章数

    from django.db.models.functions import TruncMonth

    month_num=models.Article.objects.all().filter(user=user).\

    annotate(month=TruncMonth('create_time')).values('month').order_by('month').annotate(c=Count('month')).values_list('month','c')

    print(month_num)

 

-templates-home_site.html

{% for foo in month_num %}

         <p><a href="">{{ foo.0|date:'Ym' }}({{ foo.1 }})</a></p>

{% endfor %}

 

(11).设置标签、分类、时间过滤文章

-BBS_new-urls.py

    url(r'(?P<username>\w+)/(?P<condition>category|tag|archive)/(?P<param>.*)', views.home_site),

 

-blog-views.py

 

    if kwargs:

        #取出kwarg的值(有名分组)

        condition=kwargs.get('condition')

        param=kwargs.get('param')

        #通过传递过来的分类,标签,时间,进行过滤

        if condition=='category':

            article_list=article_list.filter(category=param)

        elif condition=='tag':

            article_list = article_list.filter(tags=param)

        else:

            #2018-12 截断成2018 12

            year,month=param.split('-')

            article_list=article_list.filter(create_time__year=year,create_time__month=month)

 

-templates-home_site.html

<p><a href="/{{ user.username }}/tag/{{ foo.2 }}">{{ foo.0 }}({{ foo.1 }})</a></p>

<p><a href="/{{ user.username }}/category/{{ foo.2 }}">{{ foo.0 }}({{ foo.1 }})</a></p>

<p><a href="/{{ user.username }}/category/{{ foo.2 }}">{{ foo.0 }}({{ foo.1 }})</a></p>

 

(13).配置详情页

-BBS_new-urls.py

    #文章详情页

    url(r'(?P<username>\w+)/article/(?P<pk>\d+).html', views.article_detail),

        

-blog-views.py

def article_detail(request,username,pk):

    user=models.UserInfo.objects.filter(username=username).first()

    blog=user.blog

    ca_num = models.Category.objects.all().filter(blog=blog).annotate(

    category_count=Count('article__title')).values_list('title', 'category_count', 'pk')

    # 查询当前站点下所有的标签,对应的文章数

    tag_num = models.Tag.objects.all().filter(blog=blog).values('nid').annotate(

    tag_count=Count('article__title')).values_list('title', 'tag_count', 'pk')

    # 查询每个月发表文章数

    from django.db.models.functions import TruncMonth

    month_num = models.Article.objects.all().filter(user=user).annotate(month=TruncMonth('create_time')).values('month').order_by('month').annotate(c=Count('month')).values_list('month', 'c')

    #文章详情页

    article=models.Article.objects.filter(pk=pk).first()

    # print(article)

    return render(request,'article.html',locals())

 

-templates-article.html

{% extends 'base.html' %}

{% block content %}

    <h3>{{ article.title }}</h3>

    <div>

        {{ article.content|safe }}

    </div>

{% endblock %}

 

 

后台管理文章展示

         后台文章列表页面,后台把当前登录用户所有的文章查出来,在前端渲染

创建后台文件管理目录backend

         建立母版back_base.html

         继承母版back_article_list.html

                   增加登录认证(@login_required()

         继承母版add_article.html(添加文章),通过form表单

         添加文档是使用kindeditor编辑器,需要先导入,修改参数调用

         textarea基础上修改id="editor_id"    <script charset="utf-8" src="/static/kindeditor/kindeditor-all.js"></script>         调用kindeditor

         通过form表单提交,使用redirect返回backend

 

测试跨站脚本攻击

         https://www.cnblogs.com/ssyfj/p/9200602.html#2beautifulsoup4%E6%A8%A1%E5%9D%97

         https://www.jb51.net/onlineread/htmlchar.htm

         读写html文件,安装BeautifulSoup4,需要使用BeautifulSoup模块soup=BeautifulSoup(content,'html.parser')

         html文档中的标签,分割到列表中tag=soup.find_all()

         通过for循环,判断标签如果为script,直接删除标签script(i.name) i.decompose

         截取文档内容做为标题 desc = soup.text[0:150] soup.text 是当前页面所有的内容,截取150个字符做文章简介

         添加文章保存的时候,文章内容:str(soup)

         article = models.Article.objects.create(title=title, desc=desc, content=str(soup), user=user)

        

文章发布(富文本编辑器的使用)

         -前端,图片上传的路由

         -csrf_token:需要携带者csrf_token extraFileUploadParams

         -filePostName 修改上传文件名字

         -后台:

                   -request.FILES  上传过来的所有文件,是一个字典,根据key,取出相应的文件对象()

                   -打开一个空文件,写入即可

                   -返回值:

                            response={'error':0,'url':'/media/upload/%s'%upload_file.name}

        

         

返回顶部