python_day22_Django-7 (博客-富文本编辑器)
2018-12-12 10:41
330 查看
博客-富文本编辑器
在这一节使用的是kindeditor富文本编辑器, 下载地址 官方文档, 官网只更新到了4.1.11, github更新到了4.1.12, 往下直接就是代码示例
1、settings.py
使用自己定义的用户模块 AUTH_USER_MODEL = "app01.UserInfo" # 静态文件目录, 可以放js css image之类的文件 STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static") ] # 用户上传的都叫media文件 MEDIA_URL = "/media/" # media配置,用户上传的文件都默认放在这个文件夹下 MEDIA_ROOT = os.path.join(BASE_DIR, "media")
2、urls.py
from django.urls import path, re_path, include urlpatterns = [ path("blog/", include("app01.urls"), name="blog"), ]
3、创建应用
python manage startapp blog settings.py文件中注册应用 INSTALLED_APPS = [ # 最后新增这一行 'app01.apps.App01Config', ] blog应用中创建urls.py文件 from django.urls import path, re_path, include from app01 import views app_name = "blog" urlpatterns = [ # 添加文件 re_path("add_article/", views.add_article, name="add_article"), # 上传图片函数 re_path("comment_article/", views.comment_article, name="comment_article"), ]
4、表结构
来源老男孩的课程
from django.db import models # Create your models here. from django.contrib.auth.models import AbstractUser class UserInfo(AbstractUser): """ 用户信息表 """ nid = models.AutoField(primary_key=True) portrait = models.FileField(upload_to="images/", default="", verbose_name="头像") create_time = models.DateTimeField(auto_now_add=True) blog = models.OneToOneField(to="Blog", to_field="nid", null=True, on_delete=models.CASCADE) def __str__(self): return self.username class Meta: verbose_name = "用户" verbose_name_plural = verbose_name class Blog(models.Model): """ 博客信息 """ nid = models.AutoField(primary_key=True) title = models.CharField(max_length=64) # 个人博客标题 site = models.CharField(max_length=32, unique=True) # 个人博客后缀 theme = models.CharField(max_length=32) # 博客主题 def __str__(self): return self.title class Meta: verbose_name = "blog站点" verbose_name_plural = verbose_name class Category(models.Model): """ 个人博客文章分类 """ nid = models.AutoField(primary_key=True) title = models.CharField(max_length=32) # 分类标题 blog = models.ForeignKey(to="Blog", to_field="nid", on_delete=models.CASCADE) # 外键关联博客,一个博客站点可以有多个分类 def __str__(self): return self.title class Meta: verbose_name = "文章分类" verbose_name_plural = verbose_name class Tag(models.Model): """ 标签 """ nid = models.AutoField(primary_key=True) title = models.CharField(max_length=32) # 标签名 blog = models.ForeignKey(to="Blog", to_field="nid", on_delete=models.CASCADE) # 所属博客 def __str__(self): return self.title class Meta: verbose_name = "标签" verbose_name_plural = verbose_name class Article(models.Model): """ 文章 """ nid = models.AutoField(primary_key=True) title = models.CharField(max_length=50, verbose_name="文章标题") # 文章标题 desc = models.CharField(max_length=255) # 文章描述 create_time = models.DateTimeField(auto_now_add=True) # 创建时间 # 评论数 comment_count = models.IntegerField(verbose_name="评论数", default=0) # 点赞数 up_count = models.IntegerField(verbose_name="点赞数", default=0) # 踩 down_count = models.IntegerField(verbose_name="踩数", default=0) category = models.ForeignKey(to="Category", to_field="nid", null=True, on_delete=models.CASCADE) user = models.ForeignKey(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 Meta: verbose_name = "文章" verbose_name_plural = verbose_name 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) class Meta: verbose_name = "文章详情" verbose_name_plural = verbose_name class Article2Tag(models.Model): """ 文章和标签的多对多关系表 """ nid = models.AutoField(primary_key=True) article = models.ForeignKey(to="Article", to_field="nid", on_delete=models.CASCADE) tag = models.ForeignKey(to="Tag", to_field="nid", on_delete=models.CASCADE) class Meta: unique_together = (("article", "tag"),) verbose_name = "文章-标签" verbose_name_plural = verbose_name def __str__(self): return "{} - {}".format(self.article.title, self.tag) class ArticleUpDown(models.Model): """ 点赞表 """ nid = models.AutoField(primary_key=True) user = models.ForeignKey(to="UserInfo", null=True, on_delete=models.CASCADE) article = models.ForeignKey(to="Article", null=True, on_delete=models.CASCADE) is_up = models.BooleanField(default=True) class Meta: unique_together = (("article", "user"),) verbose_name = "文章点赞" verbose_name_plural = verbose_name class Comment(models.Model): """ 评论表 """ nid = models.AutoField(primary_key=True) article = models.ForeignKey(to="Article", to_field="nid", on_delete=models.CASCADE) user = models.ForeignKey(to="UserInfo", to_field="nid", on_delete=models.CASCADE) content = models.CharField(max_length=255) # 评论内容 create_time = models.DateTimeField(auto_now_add=True) parent_comment = models.ForeignKey("self", null=True, blank=True, on_delete=models.CASCADE) # blank=True 在django admin里面可以不填 def __str__(self): return self.content class Meta: verbose_name = "评论" verbose_name_plural = verbose_name 迁移数据 python manage makemigrations python manage migrate 每次修改完modle.py文件都需要执行这两行迁移数据命令, 执行完之后可以应用中的migrations包中看到执行的sql语句
5、views.py
视图函数 def add_article(request): print(request.POST) if request.method == "POST": title = request.POST.get("title") content = request.POST.get("textarea_content") user = request.user article_obj = Article.objects.create(user=user, title=title, desc=content[0:50]) ArticleDetail.objects.create(content=content, article=article_obj) return HttpResponse("添加成功") return render(request, "blog/add_article.html") def comment_article(request): print(request.FILES) filename = request.FILES.get("image_obj") path = os.path.join(settings.MEDIA_ROOT, "user_upload", filename.name) with open(path, "wb") as F: for line in filename: F.write(line) urls = "/media/user_upload/{0}".format(filename.name) res = { "error": 0, "url": urls, } ''' //成功时 http://kindeditor.net/docs/upload.html { "error" : 0, "url" : "http://www.example.com/path/to/file.ext" } //失败时 { "error" : 1, "message" : "错误信息" } ''' return JsonResponse(res)
6、add_article.html
在templaters中新建blog文件夹 创建add_article.html文件 {% extends 'base.html' %} {% load static %} {% block content %} <div class="container"> <div class="row"> <div class="col-md-2"></div> <div class="col-md-10"> <div id="Editor_Edit"> <div id="Editor_Edit_Header" class="CollapsibleTitle"> <span id="Editor_Edit_headerTitle">添加文章</span> </div> <form action="" method="post"> <div> <label for="">标题</label> <input type="text" class="form-control" style="height: 30px;" name="title"> </div> <div class="Editor_content"> <p>内容(kindeditor编辑器,点击上传图片,可批量上传)</p> <textarea cols="80px" rows="10px" name="textarea_content" id="editor_id"></textarea> <input type="submit" value="提交文章"> </div> {% csrf_token %} </form> </div> </div> </div> </div> <script charset="utf-8" src="{% static 'kindeditor/kindeditor-all.js' %}"></script> <script src="{% static 'jquery-3.3.1.js' %}"></script> <script> KindEditor.ready(function (K) { window.editor = K.create('#editor_id', { width: '100%', height: "400px", resizeType: 1, uploadJson: "{% url 'blog:comment_article' %}", extraFileUploadParams: { csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val() }, filePostName: "image_obj", }); }); </script> {% endblock %} base.html文件 index.html用于主页展示 public.css 样式文件 看附件
效果图
上传图片
保存之后在页面中展示会如下, 样式会乱
7、引入beautifulsoup4
安装 pip install beautifulsoup4 修改视图函数 views.py from bs4 import BeautifulSoup def add_article(request): print(request.POST) if request.method == "POST": title = request.POST.get("title") content = request.POST.get("textarea_content") user = request.user bs = BeautifulSoup(content, "html.parser") # 将html解析成字符串 desc = bs.text[0:50]+"...." # 只要前50个字符并且加上... article_obj = Article.objects.create(user=user, title=title, desc=desc) ArticleDetail.objects.create(content=content, article=article_obj) return HttpResponse("添加成功") return render(request, "blog/add_article.html") 重新添加带有html标签的文章
最终显示就正常了
过滤html标签 def add_article(request): print(request.POST) if request.method == "POST": title = request.POST.get("title") content = request.POST.get("textarea_content") user = request.user bs = BeautifulSoup(content, "html.parser") # 将html解析成字符串 desc = bs.text[0:50]+"...." # 只要前50个字符并且加上... # 查看所有的html标签 for line in bs.find_all(): # 如果名称中包含script标签或者其它,那么就删除它 if line.name in ["script"]: line.decompose() article_obj = Article.objects.create(user=user, title=title, desc=desc) # 将删除标签之后的文本保存到数据库中 ArticleDetail.objects.create(content=str(bs), article=article_obj) return HttpResponse("添加成功") return render(request, "blog/add_article.html")
相关文章推荐
- Python学习笔记24:Django搭建简单的博客网站(二)
- 前言:写python和django博客的背景
- 用Python和Django实现多用户博客系统(二)——UUBlog
- 使用python和Django完成博客数据库的迁移方法
- 自学python-django已经有一段时间。从今天开始写博客记录点滴经验与大家分享。
- Python使用Django实现博客系统完整版
- 前言:写python和django博客的背景
- python Django 搭建简单的个人博客网站(一)
- [python]使用django快速生成自己的博客小站,含详细部署方法
- 简易博客开发(8)----django1.9 博客部署到pythonanywhere上
- Python利用 Django完整的开发一个博客系统
- 用Python和Django实现多用户博客系统——UUBlog
- Django+python+eclipse 快速搭建博客blog .
- Python采用Django开发自己的博客系统
- 在 Windows Azure 网站上使用 Django、Python 和 MySQL:创建博客应用程序
- Django+python+eclipse 快速搭建博客blog
- 这几天有django和python做了一个多用户博客系统(可选择模板) 没完成,先分享下
- 用Python和Django实现多用户博客系统——UUBlog
- Django实现的博客系统中使用富文本编辑器ckeditor
- Python之Django框架搭建一个简易的博客