前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于 Django 的个人网站(2)

基于 Django 的个人网站(2)

作者头像
不可言诉的深渊
发布2020-05-27 11:38:55
2.2K0
发布2020-05-27 11:38:55
举报
文章被收录于专栏:Python机器学习算法说书人
上回说到,因为文章内容的数据类型是文本字段,文本字段只能输入字符,图片就不行了,当时我给出了两种方案——markdown 和富文本编辑器,我决定选择富文本编辑器,因为 Django 的富文本编辑器插件有很多,在这很多个插件中,我决定选择django-ckeditor。

django-ckeditor 的安装

django-ckeditor 的安装非常简单,直接:pip install django-ckeditor 就行了,安装完成之后如图所示。

django-ckeditor 的使用

使用 django-ckeditor 非常简单,因为我这里安装的是 django-ckeditor-5,和 django-ckeditor 差不多,但是也还是有一些区别的。下面直接回到正题,我们打开 PersonalWebsite\settings.py 里面找到 INSTALLED_APPS,在这个列表中添加一项名叫 django_ckeditor_5 的 app,如下所示。

代码语言:javascript
复制
INSTALLED_APPS = [
    'personal_website.apps.PersonalWebsiteConfig',

    'django_ckeditor_5',

    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

然后打开 PersonalWebsite\urls.py,配置一下 URL,代码如下:

代码语言:javascript
复制
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
    path('admin/', admin.site.urls),
    path('ckeditor5/', include('django_ckeditor_5.urls')),
]+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

接下来去修改 PersonalWebsite\settings.py 文件,去里面添加相关的信息。添加的信息如下:

代码语言:javascript
复制
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
customColorPalette = [
    {
        'color': 'hsl(4, 90%, 58%)',
        'label': 'Red'
    },
    {
        'color': 'hsl(340, 82%, 52%)',
        'label': 'Pink'
    },
    {
        'color': 'hsl(291, 64%, 42%)',
        'label': 'Purple'
    },
    {
        'color': 'hsl(262, 52%, 47%)',
        'label': 'Deep Purple'
    },
    {
        'color': 'hsl(231, 48%, 48%)',
        'label': 'Indigo'
    },
    {
        'color': 'hsl(207, 90%, 54%)',
        'label': 'Blue'
    },
]
CKEDITOR_5_CONFIGS = {
    'default': {
        'toolbar': ['heading', '|', 'bold', 'italic', 'link',
                    'bulletedList', 'numberedList', 'blockQuote', 'imageUpload', ],

    },
    'extends': {
        'blockToolbar': [
            'paragraph', 'heading1', 'heading2', 'heading3',
            '|',
            'bulletedList', 'numberedList',
            '|',
            'blockQuote', 'imageUpload'
        ],
        'toolbar': ['heading', '|', 'outdent', 'indent', '|', 'bold', 'italic', 'link', 'underline', 'strikethrough',
                    'code', 'subscript', 'superscript', 'highlight', '|',
                    'bulletedList', 'numberedList', 'todoList', '|',  'blockQuote', 'imageUpload', '|',
                    'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor', 'mediaEmbed', 'removeFormat',
                    'insertTable', ],
        'image': {
            'toolbar': ['imageTextAlternative', 'imageTitle', '|', 'imageStyle:alignLeft', 'imageStyle:full',
                        'imageStyle:alignRight', 'imageStyle:alignCenter', 'imageStyle:side',  '|'],
            'styles': [
                'full',
                'side',
                'alignLeft',
                'alignRight',
                'alignCenter',
            ]

        },
        'table': {
            'contentToolbar': ['tableColumn', 'tableRow', 'mergeTableCells',
                               'tableProperties', 'tableCellProperties'],
            'tableProperties': {
                'borderColors': customColorPalette,
                'backgroundColors': customColorPalette
            },
            'tableCellProperties': {
                'borderColors': customColorPalette,
                'backgroundColors': customColorPalette
            }
        },
        'heading': {
            'options': [
                {'model': 'paragraph', 'title': 'Paragraph', 'class': 'ck-heading_paragraph'},
                {'model': 'heading1', 'view': 'h1', 'title': 'Heading 1', 'class': 'ck-heading_heading1'},
                {'model': 'heading2', 'view': 'h2', 'title': 'Heading 2', 'class': 'ck-heading_heading2'},
                {'model': 'heading3', 'view': 'h3', 'title': 'Heading 3', 'class': 'ck-heading_heading3'}
            ]
        }
    }
}

然后就去 personal_website\models.py 里面把文章内容字段改成富文本类型字段,代码如下。

代码语言:javascript
复制
from django.db import models
from django_ckeditor_5.fields import CKEditor5Field


# Create your models here.
class Category(models.Model):
    name = models.CharField(max_length=255, unique=True)

    def __str__(self):
        return self.name


class Article(models.Model):
    title = models.CharField(max_length=255, unique=True)
    abstract = models.CharField(max_length=255)
    content = CKEditor5Field(max_length=65535)
    state = models.PositiveSmallIntegerField(choices=((0, '未发布'), (1, '已发布')), default=0)
    categories = models.ManyToManyField(Category)

    def __str__(self):
        return self.title

改好之后我们就去进行数据迁移(过程上回已经说过了),迁移完成之后打开管理后台的增加文章界面看看,如图所示。

我们可以发现按钮太少了,连代码块都没有,只不过仔细观察 CKEDITOR_5_CONFIGS 可以发现里面一共有两个设置,一个是 default,一个是 extends,默认用的是 default,很明显 extends 功能更多,要想使用 extends,我们只要把 extends 改成 default,然后把 default 的键值对给删除不就行了吗?下面看一下 CKEDITOR_5_CONFIGS。

代码语言:javascript
复制
CKEDITOR_5_CONFIGS = {
    'default': {
        'blockToolbar': [
            'paragraph', 'heading1', 'heading2', 'heading3',
            '|',
            'bulletedList', 'numberedList',
            '|',
            'blockQuote', 'imageUpload'
        ],
        'toolbar': ['heading', '|', 'outdent', 'indent', '|', 'bold', 'italic', 'link', 'underline', 'strikethrough',
                    'code', 'subscript', 'superscript', 'highlight', '|',
                    'bulletedList', 'numberedList', 'todoList', '|',  'blockQuote', 'imageUpload', '|',
                    'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor', 'mediaEmbed', 'removeFormat',
                    'insertTable', ],
        'image': {
            'toolbar': ['imageTextAlternative', 'imageTitle', '|', 'imageStyle:alignLeft', 'imageStyle:full',
                        'imageStyle:alignRight', 'imageStyle:alignCenter', 'imageStyle:side',  '|'],
            'styles': [
                'full',
                'side',
                'alignLeft',
                'alignRight',
                'alignCenter',
            ]

        },
        'table': {
            'contentToolbar': ['tableColumn', 'tableRow', 'mergeTableCells',
                               'tableProperties', 'tableCellProperties'],
            'tableProperties': {
                'borderColors': customColorPalette,
                'backgroundColors': customColorPalette
            },
            'tableCellProperties': {
                'borderColors': customColorPalette,
                'backgroundColors': customColorPalette
            }
        },
        'heading': {
            'options': [
                {'model': 'paragraph', 'title': 'Paragraph', 'class': 'ck-heading_paragraph'},
                {'model': 'heading1', 'view': 'h1', 'title': 'Heading 1', 'class': 'ck-heading_heading1'},
                {'model': 'heading2', 'view': 'h2', 'title': 'Heading 2', 'class': 'ck-heading_heading2'},
                {'model': 'heading3', 'view': 'h3', 'title': 'Heading 3', 'class': 'ck-heading_heading3'}
            ]
        }
    }
}

然后看一下增加文章页面,如图所示。

可以发现功能很明显的多了不少,代码块也有了,到此为止后台部分全部结束了,接着去编写前台的代码。

前台实现

为了让前台拿到后台的数据,我们首先去编写视图层的代码,打开 personal_website\views.py 进去编写代码,如下所示。

代码语言:javascript
复制
from django.shortcuts import render
from django.views.generic import ListView
from.models import Article


# Create your views here.
class IndexView(ListView):
    context_object_name = 'articles'
    paginate_by = 10
    queryset = Article.objects.filter(state=1)
    template_name = 'index.html'

视图层完事之后我们就需要去编写模板层,也就是 html 文件,并把数据显示到 html 上面,打开 templates\index.html,编写如下所示的代码。

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>陈志豪的个人网站</title>
</head>
<body>
<!--suppress HtmlDeprecatedAttribute -->
<h1 align="center">陈志豪的个人网站</h1>
{% for article in articles %}
    <h2>{{ article.title }}</h2>
    <p>{{ article.abstract }}</p>
{% endfor %}
<p>
    {% if is_paginated %}
        {% if page_obj.has_previous %}
            <a href="?page={{ page_obj.previous_page_number }}">上一页</a>
        {% endif %}
        &nbsp;第&nbsp;{{ page_obj.number }}&nbsp;页/共&nbsp;{{ page_obj.paginator.num_pages }}&nbsp;页&nbsp;
        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}">下一页</a>
        {% endif %}
    {% endif %}
</p>
</body>
</html>

接着去配置一下 URL,打开 PersonalWebsite\urls.py,编写的代码如下所示:

代码语言:javascript
复制
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from personal_website.views import IndexView
urlpatterns = [
    path('admin/', admin.site.urls),
    path("ckeditor5/", include('django_ckeditor_5.urls')),
    path('', IndexView.as_view()),
]+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

在运行程序之前我为了测试分页功能是否可以使用,可以尝试添加一些文章数据,当然也有简单的方法,修改 IndexView 的 paginate_by 值,每一页显示的内容变少自然就会分页了,我把这个值直接改成了 1,一页只显示一条数据,下面来看一下效果,如图所示。

主页面完成了,接下来我们就去编写文章详情页面,首先是打开 personal_website\views.py 去编写文章详情页面视图,代码如下:

代码语言:javascript
复制
from django.shortcuts import render
from django.views.generic import DetailView, ListView
from.models import Article


# Create your views here.
class IndexView(ListView):
    context_object_name = 'articles'
    paginate_by = 10
    queryset = Article.objects.filter(state=1).order_by('id')
    template_name = 'index.html'


class ArticleDetailView(DetailView):
    context_object_name = 'article'
    model = Article
    template_name = 'article_detail.html'

下面添加的 ArticleDetailView 就是文章详情页面视图类,接着去编写其对应的模板 html 文件,打开 templates\article_detail.html,代码如下:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ article.title }}</title>
</head>
<body>
<!--suppress HtmlDeprecatedAttribute -->
<h1 align="center">{{ article.title }}</h1>
<p>{{ article.abstract }}</p>
<p>{{ article.content }}</p>
</body>
</html>

然后就是配置 URL,打开 PersonalWebsite\urls.py,代码如下:

代码语言:javascript
复制
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from personal_website.views import IndexView, ArticleDetailView
urlpatterns = [
    path('admin/', admin.site.urls),
    path('ckeditor5/', include('django_ckeditor_5.urls')),
    path('', IndexView.as_view()),
    path('articles/<pk>', ArticleDetailView.as_view())
]+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

我们可以简单测试一下,进入主页,如图所示。

随便点击一个标题超链接就可以进入文章详情页面,如图所示。

我们可以发现内容部分多了标签,这是富文本编辑器造成的问题,我们直接修改 templates\article_detail.html 代码,如下所示:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ article.title }}</title>
</head>
<body>
<!--suppress HtmlDeprecatedAttribute -->
<h1 align="center">{{ article.title }}</h1>
<p>{{ article.abstract }}</p>
<p>{{ article.content|safe }}</p>
</body>
</html>

可以发现,在文章内容显示多了一个 safe,再去看一下效果,如图所示。

很明显的修改成功了,在编写其他代码之前我们先去测试这个富文本编辑器中的所有格式是否都可以被正常的显示,我们去增加一篇文章。

增加文章之后我们进入文章详情页面,看看是不是富文本可以正常显示,如图所示。

显示的确实是正常的,就是代码没有高亮显示,往下滑还会发现图片和表格没有居中显示,基本上算是正常了,就差样式了,至于如何修改样式我们明天再说。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python机器学习算法说书人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档