BBS项目补充知识(后台添加文章、修改文章功能完善)

BBS项目补充知识(后台添加文章、修改文章功能完善)

1. 添加文章功能实现

# 修改 app02的views.py中 添加文章功能:

from django.http import JsonResponse

# 添加文章
def add_article(request):
    # 1. 接收参数
    if request.method == 'POST':
        title = request.POST.get('title')
        content = request.POST.get('content')
        cate_id = request.POST.get('cate')
        tag_list = request.POST.getlist('tags')

        # 2. 验证参数

        # 3. 切掉内容的前100字
        desc = content[0:100]

        # 4. 入库:article_obj返回是当前插入数据的对象,有了对象,就可以拿到当前文章的id
        '''由于我们没有使用auth模块,所以,这里不能使用request.user,从session中手动获取'''
        user_obj = models.UserInfo.objects.filter(pk=request.session.get('id')).first()
        article_obj = models.Article.objects.create(title=title,
                                                    desc=desc,
                                                    content=content,
                                                    category_id=cate_id,
                                                    # blog=request.user.blog
                                                    blog_id=user_obj.blog_id
                                                    )

        # 5. 处理标签id,操作第三张表,因为创建的第三张表是我们自己创建的,所以,add方法不能用了
        # 因此,我们需要手动来操作表进行入库
        '''由于操作数据库的次数过多,我们采用批量添加的形式,对数据库进行优化'''
        article_obj_list = []
        for i in tag_list:
            tag_article_obj = models.Article2Tag(article_id=article_obj.pk, tag_id=i)
            article_obj_list.append(tag_article_obj)

        '''这样做的好处是:不管有多少个标签要入库,都是只操作一次数据库。'''
        models.Article2Tag.objects.bulk_create(article_obj_list)

        return redirect('/app02/article_list/')


    # 查询出所有的分类列表
    cate_list = models.Category.objects.all()
    # 查询出所有的标签列表
    tag_list = models.Tag.objects.all()
    
    return render(request, 'backend/add_article.html', locals())



# 修改 add_article.html文件内 body内的 div标签:
<div class="container-fluid">
    <div class="row">
        <h1 class="text-center">添加文章</h1>
        <div class="col-md-8 col-md-offset-2">

            <form action="" method="post">

                <div class="form-group">
                    <label for="title">文章标题</label>
                    <input type="text" id="title" name="title" class="form-control">
                </div>

                <div class="form-group">
                    <label for="title">文章内容</label>
                    <textarea id="editor_id" name="content" style="width:500px;height:600px;"></textarea>
                </div>

                <div class="form-group">
                    <label for="title">文章分类</label>
                    <select name="cate" id="" class="form-control">
                        {% for cate in cate_list %}
                            <option value="{{ cate.pk }}">{{ cate.title }}</option>
                        {% endfor %}
                    </select>
                </div>

                <div class="form-group">
                    <label for="title">文章标签</label>
                    {% for tag in tag_list %}
                        <input type="checkbox" name="tags" value="{{ tag.pk }}"> {{ tag.title }}
                    {% endfor %}
                </div>

                <input type="submit" class="btn btn-success" value="提交">
            </form>
        </div>
    </div>
</div>

image

image

2. 完善数据库存储信息

"""
数据库中文章表保存的文章内容是原生的html标签

为了截取文章的前100个汉字,不能使用直接切片,该方法截取出来的是html标签的范围

如何解决?
	我们需要借助bs4模块,这个模块在爬虫当中用的超级多,是爬虫中用的最大的一个模块之一
"""
# 修改 app02的views.py中 添加文章功能中 # 3. 切剪内容的前100字 4. 入库:
        # 3. 切剪内容的前100字
        # desc = content[0:100]
        """
        为了截取文章的前100个汉字,不能使用该方法直接切片,截取出来的是html标签前100字符
        
        # 如何解决?
            我们需要借助bs4模块,这个模块在爬虫当中用的超级多,是爬虫中用的最大的一个模块之一
        """
        # 使用该模块:bs4,
        # 你还需要安装解析器模块
        soup = BeautifulSoup(content, 'lxml')
        tags = soup.find_all()

        # 支持循环
        for tag in tags:
            '''针对xss攻击的核心:不能有script标签,如果没有这个标签,js代码就不会执行'''
            print(tag.name)
            # 判断是不是有script标签
            if tag.name == 'script':
                # 删除script标签
                tag.decompose()

        # desc = soup.text  # 只拿文本内容
        desc = soup.text[0:100]  # 只拿文本内容

        # 4. 入库:article_obj返回是当前插入数据的对象,有了对象,就可以拿到当前文章的id
        '''由于我们没有使用auth模块,所以,这里不能使用request.user,从session中手动获取'''
        user_obj = models.UserInfo.objects.filter(pk=request.session.get('id')).first()
        article_obj = models.Article.objects.create(title=title,
                                                    desc=desc,
                                                    content=str(soup),
                                                    category_id=cate_id,
                                                    # blog=request.user.blog
                                                    blog_id=user_obj.blog_id
                                                    )

image

image

image

3. 修改文章功能前端页面逻辑实现

# 修改app02下 article_list.html中修改a标签:
<a href="/app02/edit/article/?id={{ article.pk }}" target="_blank" class="btn btn-success">修改</a>


# app02下 添加路由:
    # 修改文章
    url(r'^edit/article/', views.edit_article),
    

# app02下 添加修改文章功能:
# 修改文章功能
def edit_article(request):
    id = request.GET.get('id')  # 文章id
    article_obj = models.Article.objects.filter(pk=id).first()

    # 第一步先找到当前文章所属的标签id
    tag_ids_obj = models.Article2Tag.objects.filter(article_id=id).values_list('tag_id')
    tag_ids = []  #
    for tag in tag_ids_obj:
        tag_id = tag[0]
        tag_ids.append(tag_id)

    # 查询出所有的分类列表
    cate_list = models.Category.objects.all()
    # 查询出所有的标签列表
    tag_list = models.Tag.objects.all()
    return render(request, 'backend/edit_article.html', locals())



# 新建edit_article.html文件:
"""将add_article.html内容复制过去并做部分修改即可 文章分类 文章标签 两个div即可"""
                <div class="form-group">
                    <label for="title">文章分类</label>
                    <select name="cate" id="" class="form-control">
                        {% for cate in cate_list %}
                            {% if article_obj.category_id == cate.pk %}
                                <option value="{{ cate.pk }}" selected>{{ cate.title }}</option>
                            {% else %}
                                <option value="{{ cate.pk }}">{{ cate.title }}</option>
                            {% endif %}
                        {% endfor %}
                    </select>
                </div>

                <div class="form-group">
                    <label for="title">文章标签</label>
                    {% for tag in tag_list %}
                        {% if tag.pk in tag_ids %}
                            <input type="checkbox" name="tags" checked value="{{ tag.pk }}"> {{ tag.title }}
                        {% else %}
                            <input type="checkbox" name="tags" value="{{ tag.pk }}"> {{ tag.title }}
                        {% endif %}
                    {% endfor %}
                </div>

image

4. 富文本编辑器上传图片

# 在edit_article.html文件中 修改 script标签内容 添加uploadJson:
            resizeType: 0,
            themeType: 'simple',
            uploadJson:'/app02/upload_img/'
        });
    });
</script>

# 在项目总路由中添加开放路径:
from django.views.static import serve
from django.conf import settings
    # 开放路径
    url(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}),
    
    
# 在app02路由中添加:
    # 编辑器上传图片
    url(r'^upload_img/', views.upload_img),
    
    
    
# app02下 views.py中 添加上传图片功能:

from django.http import JsonResponse
from django.conf import settings
import os

# 上传图片功能
def upload_img(request):
    '''
        //成功时
            {
                    "error" : 0,
                    "url" : "http://www.example.com/path/to/file.ext"
            }

        //失败时
            {
                    "error" : 1,
                    "message" : "错误信息"
            }
        :param request:
        :return:
    '''

    back_dic = {
        "error": 0,
        "url": ""
    }

    if request.method == 'POST':
        file_obj = request.FILES.get('imgFile')
        # 拼接要上传的文件路径
        file_dir = os.path.join(settings.BASE_DIR, 'media', 'article_img')
        if not os.path.exists(file_dir):
            os.mkdir(file_dir)

        '''
        解决文件名被覆盖问题
            1. 截取图片的后缀名
            2. 生成随机字符串
            3. 随机字符串 + 后缀名
        '''

        # 拼接文件的完整路径
        file_path = os.path.join(file_dir, file_obj.name)
        # /media/article_img/123.png

        # 上传文件
        with open(file_path, 'wb') as f:
            for line in file_obj:
                f.write(line)
        back_dic['url'] = '/media/article_img/%s' % file_obj.name

        return JsonResponse(back_dic)

image

image

posted @   Deity_JGX  阅读(64)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示