zoukankan      html  css  js  c++  java
  • BBS

    一、添加文章

    注:

    后台管理页面,应该有个新得 app

    /blog/backend/ # 文章列表页
    /blog/add_article/ # 添加文章
    # 后台管理
    re_path(r'backend/$', views.backend),
    re_path(r'add_article/$', views.add_article),

    二、文本编辑器

    文本编辑器 kindeditor  本质上就是(css+js)
    官网:
    http://kindeditor.net/demo.php
    http://kindeditor.net/doc.php

    使用:
      
    kindeditor
    <script src="/static/kindeditor/kindeditor-all.js"></script>

    <textarea name="article_con" id="article_box" cols="30" rows="10"></textarea>

    KindEditor.ready(function (k) {
    window.editor = k.create('#article_box')
    ...
    })

    KindEditor会覆盖textarea, 注意 id

      初始化 参数

    http://kindeditor.net/docs/option.html
      

    add_article.html  

    注意:kindeditor 参数配置

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>add_article</title>
        <style type="text/css">
            *{padding: 0;margin: 0}
            .header{ width: 100%; height: 60px;background-color: green}
            .content{ padding-top: 30px;}
        </style>
    </head>
    <body>
    
    <div class="header">
    
    </div>
    
    <div class="content">
        <form action="" method="post">
            {% csrf_token %}
            <div class="title">
                标题: <input type="text" name="title" >
            </div>
            <div>
                内容:<br>
                <textarea name="article_con" id="article_box" cols="30" rows="10"></textarea>
            </div>
            <input type="submit">
        </form>
    
    </div>
    
    {% csrf_token %}
        <script src="/static/js/jquery-3.2.1.min.js"></script>
        <script src="/static/kindeditor/kindeditor-all.js"></script>
        <script charset="utf-8" src="/static/kindeditor/lang/zh-CN.js"></script>
    
        <script type="text/javascript">
            KindEditor.ready(function (k) {   // 将 自己写得 textarea id=article_box 覆盖
                window.editor = k.create('#article_box',{
                    800,
                    height:400,
                    items:[  // 留可选得!!
                        'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste',
                        'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright',
                        'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript',
                        'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/',
                        'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold',
                        'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'multiimage',
                        'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak',
                        'anchor', 'link', 'unlink', '|', 'about'
                    ],
                    resizeType:0, 
                    uploadJson:'upload_img/',
                    extraFileUploadParams:{"csrfmiddlewaretoken":$('input[name=csrfmiddlewaretoken]').val()},
                    filePostName:'img'
                })
            })
    
        </script>
    
    </body>
    </html>

    三、上传文件

    注意点:

    之前学过:form ajax  
    这次是:编辑器发文件:实质是 ajax的post

    注意:
    1.参数配置
    uploadJson:'upload_img/', # 得是相对路径,否则会报错!
    extraFileUploadParams:{"csrfmiddlewaretoken":$('input[name=csrfmiddlewaretoken]').val()},
    filePostName:'img'

    2.url
    re_path(r'upload_img/', views.upload_img),

    3.用户文件存放 /media/article_imgs/...
    img_obj = request.FILES.get('img')
    # MEDIA_ROOT = os.path.join(BASE_DIR,'blog','media')

    media_path = settings.MEDIA_ROOT
    path = os.path.join(media_path,'article_imgs',img_obj.name)

    4.写文件
    with open(path,'wb') as f:
    for line in img_obj:
    f.write(line)

    5.返回json
    res = {
    "url":"/media/article_imgs/"+img_obj.name,
    "error":0
    }
    return HttpResponse(json.dumps(res))

     code:

    from cnblog import settings
    import os
    import json
    def upload_img(request):
    
        print('files:',request.FILES)  # files 才能拿到文件
        # <MultiValueDict: {'imgFile': [<InMemoryUploadedFile: lufei.jpg (image/jpeg)>]}>
        # 可以自己定义 文件名!!  filePostName:'img'
        # < MultiValueDict: {'img': [ < InMemoryUploadedFile: lufei.jpg(image / jpeg) >]} >
    
        img_obj = request.FILES.get('img')
    
        # MEDIA_ROOT = os.path.join(BASE_DIR,'blog','media')
        media_path = settings.MEDIA_ROOT
        path = os.path.join(media_path,'article_imgs',img_obj.name)
    
        with open(path,'wb') as f:
            for line in img_obj:
                f.write(line)
    
        res = {
            "url":"/media/article_imgs/"+img_obj.name,
            "error":0
        }
        return HttpResponse(json.dumps(res))

    四、提交文章 - BeautifulSoup 

    总结:

    Article:
    nid, title, desc, create_time, comment_count, up_count, down_count, category, user, tags,
    ArticleDetail:
    nid,content,article

    注意点:
    title = request.POST.get('title')
    article_con = request.POST.get('article_con')

    0.防止XSS攻击:引入 (BeautifulSoup)
    https://www.cnblogs.com/yuanchenqi/articles/7617280.html
    http://beautifulsoup.readthedocs.io/zh_CN/latest/

    简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页解析数据。

    。。。详细使用。。。

    pip3 install beautifulsoup4
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(article_con,'html.parser')

    # 过滤 script
    for tag in soup.find_all():
    if tag.name == 'script':
    tag.decompose() # 删除了所有的script标签及内容

    获取desc
    1.
    if desc = article_con[0:150]
    会有问题:article_con 内容中含有标签,截取会截不全,导致有的标签没有闭合,样式错乱!
    2.
    图片代码不截,只截文本 soup.text[0:150] 会有一点问题
    引入:beautifulsoup 针对标签,字符串,做过滤查询。

    soup = BeautifulSoup(article_con,'html.parser')
    desc = soup.text[0:150]
    but: 有一点问题 soup.text # text 把转义的字符又返回去了!!
    eg: &lt;script&gt;alert(555)&lt;/script&gt;
    转为:<script>alert(555)</script>,存到库里有问题的!
    所以:
    desc = soup.text[0:150]
    desc = desc.replace('<', '&lt;').replace('>', '&gt;')

    <p>{{ article.desc|safe }}</p>
      3.soup.prettify()

     code:

    def add_article(request):
        if request.method == 'POST':
            title = request.POST.get('title')
            article_con = request.POST.get('article_con')
    
            from bs4 import BeautifulSoup
            soup = BeautifulSoup(article_con, 'html.parser')
    
            print('text1:', soup.text)  # text 把 转义的字符又返回去了!!
    
            # 过滤 script
            for tag in soup.find_all():
                if tag.name == 'script':
                    tag.decompose()  # 删除了所有的script标签
    
            desc = soup.text[0:150]
            desc = desc.replace('<', '&lt;').replace('>', '&gt;')
    
            article_obj = Article.objects.create(title=title, desc=desc,user=request.user)
            # soup.prettify() == str(soup)
            ArticleDetail.objects.create(content=soup.prettify(),article=article_obj)
    
            return HttpResponse('提交成功')
    
        else:
            return render(request, 'add_article.html')
    class Article(models.Model):
        """
        文章信息
        """
        nid = models.AutoField(primary_key=True)
        title = models.CharField(max_length=50, verbose_name='文章标题')
        desc = models.CharField(max_length=255, verbose_name='文章描述')
        create_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True)
        
        comment_count = models.IntegerField(default=0)  # 为了查询时,效率高!
        up_count = models.IntegerField(default=0)
        down_count = models.IntegerField(default=0)
    
        category = models.ForeignKey(to='Category', to_field='nid', null=True, on_delete=models.CASCADE)
        user = models.ForeignKey(verbose_name='作者', to='UserInfo', to_field='nid', on_delete=models.CASCADE)
    
        tags = models.ManyToManyField(
            to='Tag',
            through='Article2Tag',
            through_fields=('article','tag'),
        )
    
        def __str__(self):
            return self.title
    
    
    class ArticleDetail(models.Model):
        """
        文章详细表
        """
        nid = models.AutoField(primary_key=True)
        content = models.TextField()
        article = models.OneToOneField(to='Article', to_field='nid', on_delete=models.CASCADE)
    models.py

    五、BBS - 原始版 

    https://github.com/alice-bj/cnblog_0

  • 相关阅读:
    ASP.NET MVC 异常捕获
    Jquery 扩展方法
    Spring.NET笔记1
    ASP.NET MVC Ninject 实现依赖注入
    ASP.NET MVC Unity实现依赖注入
    windows service
    反射用法
    抽象工厂核心反射
    (C#)中的DataSet、string、DataTable等对象转换成Json
    .NET批量删除代码前的行号
  • 原文地址:https://www.cnblogs.com/alice-bj/p/9158412.html
Copyright © 2011-2022 走看看