建站日记

今天我打算重新建立我的个人博客网站,由于以前的网站媒体文件和图像文件加载不出来导致网页界面过丑,我还是重新写一个网站吧,可能需要花费一些时间,顺便再回顾下django的一些知识,同时记录下来也方便以后的回顾,同时欢迎访问我的博客:catfish的个人博客

配置环境

默认已经安装好了虚拟环境,如果虚拟环境没有安装好参照文章:虚拟环境

然后创建虚拟环境:

mkvirtualenv myproject_env

然后自动进入了创建的虚拟环境,安装django:

pip install django

运行时报错:

pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out.

估计是安装速度过慢,我还是采用清华的镜像源:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple django

然后使用如下命令判断安装是否成功:

django-admin --version

当前版本为3.1.1,安装成功!

开始开发——后台开发!

首先素质三联:

django-admin startproject myproject
cd myproject
py manage.py startapp myapp
py manage.py migrate

然后在settings.py文件中激活app,并汉化后台:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 自己写的app
    'myapp',
]

# Internationalization

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

然后编写models.py文件:

from django.db import models

class Book(models.Model):
    name = models.CharField(max_length=30, verbose_name="书名")
    
    class Meta:
        verbose_name = "书籍"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class Article(models.Model):
    STATUS_CHOICE = (("draft", "草稿"), ("published", "发布中"))
    title = models.CharField(max_length=30, verbose_name="标题")
    book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name="article", verbose_name="书名")
    content = models.TextField(verbose_name="正文")
    status = models.CharField(max_length=10, choices=STATUS_CHOICE, default="draft", verbose_name="文章状态")
    priority = models.IntegerField(default=0, verbose_name="优先级")
    look = models.IntegerField(default=0, verbose_name="浏览量")
    datetime = models.DateTimeField(auto_now_add=True, verbose_name="发布日期")

    def book_name(self):
        return self.book.name
    
    def get_absolute_url(self):
        return "/article/{}".format(self.id)

    class Meta:
        ordering = ('-priority',)

    def __str__(self):
        return self.title

由于改变了models.py文件,我们需要重新导入数据库信息:

py manage.py makemigrations
py manage.py migrate

然后创建超级用户:

py manage.py createsuperuser

设置访问用户名和密码即可,自定义模型到后台显示,编辑admin.py文件:

from django.contrib import admin
from . import models

def make_published(modeladmin, request, queryset):
    queryset.update(status='published')
make_published.short_description = "一键发布"

@admin.register(models.Article)
class ArticleAdmin(admin.ModelAdmin):
    actions = [make_published,]
    list_display = ["title", "book_name", "status", "priority",]
    search_fields = ['title', "content"]
    list_editable = ["priority",]

@admin.register(models.Book)
class BookAdmin(admin.ModelAdmin):
    list_display = ['name',]

然后在models.py文件中添加自定义默认管理器:

from django.db import models

# 自定义管理器
class PublishedManager(models.Manager):
    def get_queryset(self):
        return super(PublishedManager, self).get_queryset().filter(status='published')

# 书籍
class Book(models.Model):
    name = models.CharField(max_length=30, verbose_name="书名")
    
    class Meta:
        verbose_name = "书籍"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

# 文章
class Article(models.Model):
    objects = models.Manager()
    published = PublishedManager()
    STATUS_CHOICE = (("draft", "草稿"), ("published", "发布中"))
    title = models.CharField(max_length=30, verbose_name="标题")
    book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name="article", verbose_name="书名")
    content = models.TextField(verbose_name="正文")
    status = models.CharField(max_length=10, choices=STATUS_CHOICE, default="draft", verbose_name="文章状态")
    priority = models.IntegerField(default=0, verbose_name="优先级")
    look = models.IntegerField(default=0)
    datetime = models.DateTimeField(auto_now_add=True, verbose_name="发布日期")

    def book_name(self):
        return self.book.name

    class Meta:
        ordering = ('priority',)
        verbose_name = "文章列表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.title

开始开发——前台开发

现在开始前台开发,然后可以配置views.py文件和urls.py文件,但是之前要先在settings.py文件中配置templates文件的路径:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates")],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

因为有很多共用代码,所以在templates目录下创建一个myapp文件夹,然后放入bose.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎光临,我的博客</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
    <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script>
    <script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
    {% block style %}{% endblock %}
    <style>
        /* 轮播图 */
        .carousel-inner img {
            width: 100%;
            height: 100%;
        }
        /* 下面的部分 */
        footer{
            background-color: black;
            color: white;
            text-align: center;
            padding-top: 30px;
            padding-bottom: 30px;
        }
    </style>
</head>
<body>
    <!-- 导航条 -->
    <nav class="navbar navbar-expand-sm bg-secondary navbar-dark">
        <ul class="navbar-nav">
            <li class="nav-item active">
                <a class="nav-link disabled" href="#">李喆的个人博客</a>
              </li>
          <li class="nav-item active">
            <a class="nav-link" href="home.html">主页</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="blog.html">博客</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="links.html">友链</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="about.html">关于我</a>
          </li>
        </ul>
      </nav>

      <!-- 轮播图 -->
      <div id="demo" class="carousel slide" data-ride="carousel">

        <ul class="carousel-indicators">
          <li data-target="#demo" data-slide-to="0" class="active"></li>
          <li data-target="#demo" data-slide-to="1"></li>
          <li data-target="#demo" data-slide-to="2"></li>
        </ul>
    
        <div class="carousel-inner">
          <div class="carousel-item active">
            <a href=""><img src="https://static.runoob.com/images/mix/img_fjords_wide.jpg"></a>
          </div>
          <div class="carousel-item">
            <a href=""><img src="https://static.runoob.com/images/mix/img_nature_wide.jpg"></a>
          </div>
          <div class="carousel-item">
            <a href=""><img src="https://static.runoob.com/images/mix/img_mountains_wide.jpg"></a>
          </div>
        </div>
       
     
        <a class="carousel-control-prev" href="#demo" data-slide="prev">
          <span class="carousel-control-prev-icon"></span>
        </a>
        <a class="carousel-control-next" href="#demo" data-slide="next">
          <span class="carousel-control-next-icon"></span>
        </a>
       
      </div>
    
{% block content %}{% endblock %}


    <footer>
        ©2019 - 2020 | CATFISH1921.COM | POWERED BY Django 2.28 & Bootstrap | 站长统计 | 服务托管于腾讯云 | 鄂ICP备19025576号-1
    </footer>
    
</body>
</html>

然后再放入home.html文件:

{% extends 'myapp/base.html' %}
{% block style %}
<style>
  /* 消除li标签的圆点 */
  li{
      list-style: none;
  }
  /* 左边的部分 */
  .main{
      margin-top: 20px;
      margin-bottom: 20px;
  }
  /* 右边的部分 */
  .other{
      margin-top: 20px;
      text-align: center;
      margin-bottom: 20px;
  }
</style>
{% endblock %}

{% block content %}
      <!-- 文章列表 -->
      <div class="container">
        <div class="row">
            <div class="col-md-8 main">
                <div class="card">
                    <div class="card-body">
                        {% for one in ones %}
                        <div class="list">
                            <h4><a href="{% url 'article' one.id %}">{{ one.title }}</a></h4>
                            <p>{{ one.content|truncatechars:100 }} ... </p>
                        </div><hr>
                        {% endfor %}
                </div>
                </div>
            </div>
            <div class="col-md-4 other">
                    <div class="card">
                      <div class="card-body">
                        <h4 class="card-title">热门文章</h4><br>
                        {% for hot in hots %}
                        <p><a href="#" class="card-link">{{ hot.title }}</a></p>
                        {% endfor %}
                      </div>
                    </div>
        </div>
      </div>
</div>
{% endblock %}

编写views.py文件:

from django.shortcuts import render

def home(request):
    return render(request, 'myapp/home.html')

在myapp中创建一个urls.py文件并写入:

from django.urls import path
from . import views

urlpatterns = [
    path("", view.home, name="home"),
]

然后在myproject中的urls.py文件中写入:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", include("myapp.urls")),
]

然后同理,可以把接下来的页面都写了,由于太过于繁琐,这里省略……

配置静态文件

然后配置加载静态文件:

# 首先配置STATIC_URL
STATIC_URL = '/static/'
# 创建对应的文件夹static
# 配置路径:
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static")
]
# 然后在模板中使用:
# {% load static %}
# <link rel="stylesheet" href="{% static 'style.css' %}">
# 如果不想每次加载都使用{% load static %},那么这样配置:
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates")],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
            'builtins':['django.templatetags.static'],
        },
    },
]

好了,静态文件就配置完了!

markdown编辑

接下来就是markdown编辑了!我到网上找了下通用的!

我们要使用的第三方插件是django-mdeditor,首先安装:

pip install django-mdeditor

如果又遇到超时错误,请使用清华快源。

接下来,我们开始我们的表演!

第一步:在settings.py文件中激活app:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 自己写的app
    'myapp',
    # 第三方app
    'mdeditor',
]

第二步,在settings.py文件中添加:

MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
MEDIA_URL = '/media/'

第三步:在urls.py中配置:

from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static   # 配置添加1
from django.conf import settings             # 配置添加2
from django.conf.urls import handler404
from myapp import views

handler404 = views.page_not_found

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", include("myapp.urls")),
    path("mdeditor/", include('mdeditor.urls')),      # 配置添加3
]

if settings.DEBUG:         # 配置添加4
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

然后再models.py文件中添加:

from mdeditor.fields import MDTextField

content = MDTextField(verbose_name="正文")

打开后台后即可!

但是我们现在遇到了一个问题:如何在页面中将markdown语法的字符串转换成html代码呢,这时候我们用到了django-markdown-deux。我觉得django-markdown-deuxdjango-mdeditor就是天生一对!现在让我们来看看django-markdown-deux的用法:

首先安装:

pip install django-markdown-deux

然后再INSTALL_APP中激活:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 自己写的app
    'myapp',
    # 第三方app
    'mdeditor',
    'markdown_deux',
]

然后直接使用即可!

{% load markdown_deux_tags %}
{{ one.content | markdown }}

然而使用过程中代码块的问题没有解决,接下来我们来解决代码块的问题!

然而我发现了一个问题,django-markdown-deux不支持```开头的代码块,所以我选择另一种实现方式:

首先安装第三方库:

pip install markdown

然后到指定视图函数中将markdown代码翻译成html代码即可!

def article(request, id):
    one = get_object_or_404(Article, pk=id)
    one.content = markdown.markdown(one.content, extensions=[
        'markdown.extensions.extra',
        'markdown.extensions.codehilite',
        'markdown.extensions.toc',
    ])
    return render(request, "myapp/article.html", locals())

最后再加个safe标签即可!

{{ one.content | safe }}

然后接下来就是代码高亮!详情查看文章:前端代码高亮

分页功能展示

当我们写的博客越来越多时,分页是我们的一个完美的途径。

然后给博客添加一些特效

相关链接为:https://blog.csdn.net/w18838020329/article/details/92813275

雪花特效:

<!-- 雪花特效 -->
<script src="http://www.lmlblog.com/winter/templets/xq/js/snowy.js"></script>
<style type="text/css">
.snow-container{position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:100001;}</style>
<div class="snow-container"></div>

部署我们的网站

Linux常用的web服务器软件:Apache,Nginx

安装教程:https://www.bilibili.com/video/BV1us411w7hd

然后配置静态文件又一个写法注意下:

STATIC_ROOT = os.path.join(BASE_DIR, 'static_collected')

最后的准备操作

pip freeze > requeriment.txt
pip install -r requeriment.txt

sqlite3数据库不能运行问题:

chmod 777 db.sqlite3
cd ..
chmod 777 *

使用django-simpleui美化后台

首先:

pip install django-simpleui

然后到app内注册即可:

INSTALLED_APPS = [
    'simpleui',              # 一定要写在最上面!
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 自己写的app
    'myapp',
    # 第三方app
    'mdeditor',
]

然后就可以用了!

posted @ 2020-10-12 22:01  小默同学  阅读(120)  评论(0编辑  收藏  举报