建站日记
今天我打算重新建立我的个人博客网站,由于以前的网站媒体文件和图像文件加载不出来导致网页界面过丑,我还是重新写一个网站吧,可能需要花费一些时间,顺便再回顾下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-deux
和django-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',
]
然后就可以用了!