django开发个人博客系统
目录
前言
项目预览
项目版本
项目构思
项目实战
登录子系统
后台美化
完整项目获取
尾言
前言
当初是在2018年写下的这篇文章,那时的django更新到了版本2.0,使用人数还是比较少的,网上的教程大多也很少。而现在随着python web框架的流行,越来越多人开始接触到了django这门技术。如今,django已经更新到了版本3.0,添加了支持异步等重要特性,但是这些特性和本篇文章基本无关。写下这篇文章的初衷是为了让刚接触django框架的童鞋可以入门上手一个项目,了解如何快速搭建一个项目,毕竟python web的优势便是快速易上手嘛【最近接触了springboot后的感触】。如今再次更新这篇博文(2020-2月),希望能够给予大家入门一定的帮助。
p.s:其实建立一个web项目需要处理的事情比较杂,我就按照我的建立习惯给大家写下这篇教程。
另外,本项目是我在重新写时完整重新搭建,所以一定可以跑通,我会写的比较仔细一点,如果你能耐心看完,必定有所收获。
【-------------------------原创不易,请勿侵权------------------------------------------------------------------】
项目预览
项目版本
运行平台:windows
Python版本:3.7
Django版本:3.0
数据库工具:sqlite
开发工具:Pycharm+vscode
依赖:pillow,django-simpleui,django_summernote
项目构思
个人博客系统属于一个非常小型的项目,不会存在高并发的情况,同时注册用户主要也就是为了评论博客内容,其实用户账号安全性也可以完全不用考虑。项目采取前后端分离的形式进行开发,前后端信息交互多数采取ajax形式(按理说动态更新页面比较友好交互,但是为了让大家感受一下这两种方式,在登录这一块采取静态跳转)。剩下的部分一次性在这里写下来大家也不一定能看的很明白,在建立项目的过程中再给大家介绍。
项目实战
请先下载静态文件 下载连接:https://pan.baidu.com/s/1Er2S63MThOfzhlbuUkTEkw 之后替换相应的文件
我们首先给我们的项目起个名字:Ericam
(1)利用命令行创建项目。
django-admin startproject Ericam
(2)创建APP
解释一下:项目中会存在登录子系统,博文管理子系统等,这些子系统每个都可以作为一个app,如此分离方便日后开发维护。但是作为一个入门项目,便不如此麻烦了。我们在整个项目只建立一个app。
由于我们准备搭建的是一个博客系统,所以就给这个APP起名为:blog
在命令行下继续输入
python manage.py startapp blog
此时文件目录结构:
介绍一下各个文件的用处
删除test.py,新建一个urls.py文件
为什么需要两个urls.py文件呢?方便分层管理,类似于一级目录,二级目录。
(3)注册app并配置静态文件目录
在settings.py文件里添加如下内容
# 配置静态文件目录
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),]
【静态文件:css,js和图片文件等,我们在这里配置了文件目录路径】
此时运行项目,用浏览器访问 http://127.0.0.1:8000/
出现一个小火箭代表我们的项目搭建成功了。
(4)
新建文件夹,如下所示(建议直接将static文件夹复制过来,本博客不会讲解css以及js):
(所有html文件存放于templates文件夹下)
新建index_unlog.html文件【作为首页,未登录时显示的页面】
我们先简单测试一下,给大家展示一下django如何通过view.py视图层显示html页面。
在index_unlog.html里:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>首页</title>
</head>
<body>个人博客系统测试
</body>
</html>
在views.py文件里:
def index_unlog(request):return render(request,'index_unlog.html')
最后我们添加一下路由地址,在与settings.py同级目录的urls.py:
urlpatterns = [path('admin/', admin.site.urls),path('blog/',include('blog.urls')),path('',views.index_unlog,name='index_unlog')
]
在新建的urls.py文件【以后我加个标号2代表该文件】里添加如下内容:
app_name = 'blog'
urlpatterns = [
]
ps:在pycharm里按alt+enter可以添加未引入的类包。
此时刷新项目,用浏览器访问 http://127.0.0.1:8000/
搞懂了每个文件的大致作用,我们便可以开始正式开发博客系统啦。
我们按照模块化进行开发。
登录子系统开发
(1)首页(未登录)-编写index_unlog.html
{% load static %}
<html lang="zh"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="author" content="Ericam_"><!-- CSS --><title>Ericam_blog</title><link rel="shortcut icon" href="{% static 'images/gt_favicon.png' %}"><link rel="stylesheet" media="screen" href="http://fonts.googleapis.com/css?family=Open+Sans:300,400,700"><link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"><link rel="stylesheet" href="{% static 'css/font-awesome.min.css' %}"><!-- Custom styles for our template --><link rel="stylesheet" href="{% static 'css/bootstrap-theme.css'%}" ><link rel="stylesheet" href="{% static 'css/log.css'%}"><link rel="stylesheet" href="{% static 'css/blog.css'%}"></head><body class="back"><!--导航栏--><div class="navbar navbar-inverse navbar-fixed-top headroom" ><div class="container"><div class="navbar-header"><!-- Button for smallest screens --><button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"><span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button><a class="navbar-brand"><img src="{%static 'css/images/lo.png'%}" alt="Progressus HTML5 template"></a></div><div class="nav navbar-nav navbar-right"><!--在这里填写登录提交 1--></div></div></div><center><div class="container"style="padding-top:300px;min-height:800px"><div class="row">,.<p class="lead"><font color="white"">个人博客系统,尽情的享用吧(〃'▽'〃)</font></p><p class="tagline"><font color="white">如果您有优秀的建议,欢迎投递哦</font></p><!--在这里填写登录提交 2--></div></div></center><footer id="footer" class="top-space"><div class="footer2"><div class="container"><p class="text-center">Copyright © 2020, Ericam_blog</p></div></div></footer>
</body>
</html>
第一句话{%load static%}代表引入静态文件(css,js等)
img,css,js等文件的引用与下述语句类似:
<link rel="stylesheet" href="{%static 'css/log.css' %}">
此时打开浏览器查看效果:
(2)登录页-login.html
{%load static%}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>登录</title><link rel="shortcut icon" href="{% static 'images/gt_favicon.png' %}"><link rel="stylesheet" href="{%static 'css/log.css' %}"><link rel="stylesheet" href="{%static 'css/semantic.css' %}"><link rel="stylesheet" href="{% static 'css/font-awesome.min.css' %}">
</head>
<body class="login"><div class="ui center aligned grid"style="margin-top: 200px"><div class="ui six wide column"><h1 class="ui teal header">Ericam blog-登录</h1><div class="ui segment"><div class="ui content"><form class="ui large form" method="post" action="{%url 'login'%}"><div class="ui stacked segment"><div class="field"><div class="ui left icon input"><input type="text" name="username" placeholder="请输入用户名"></div></div><div class="field"><div class="ui left icon input"><input type="password" name="password" placeholder="请输入密码"></div></div>{{ error }}<br><a class="pull-right field" >忘记密码</a><button class="ui fluid large teal button" type="submit">登陆</button></div><div class="ui error message"></div></form><div class="ui message">New to us? <a>注册</a></div></div></div></div></div>
</body>
</html>
添加路由信息:
urlpatterns = [path('admin/', admin.site.urls),path('blog/',include('blog.urls')),path('',views.index_unlog,name='index_unlog'),path('login',views.login,name='login')
]
添加视图层views.py内容:
def login(request):return render(request,'login.html')
此时预览:
在index_unlog.html里添加内容:
<!--在这里填写登录提交 1-->
<a class="btn" href="{% url 'login' %}">登录 / 注册</a></li><!--在这里填写登录提交 2-->
<p><a class="btn btn-action btn-lg" role="button" href="{% url 'login' %}">START NOW</a></p>
为了实现登录功能,我们首先需要构造一个用户表
打开models.py文件
from django.db import models
from django.contrib import admin
from django.urls import reverse
from django.utils.timezone import now# Create your models here.class User(models.Model):username = models.CharField(max_length = 50)password = models.CharField(max_length = 200)nickname = models.CharField(max_length = 50,default='匿名')email = models.EmailField()created_time = models.CharField(max_length=50,default=now)comment_num = models.PositiveIntegerField(verbose_name='评论数', default=0)avatar = models.ImageField(upload_to = 'media', default="media/default.png")def __str__(self):return self.usernamedef comment(self):self.comment_num += 1self.save(update_fields=['comment_num'])def comment_del(self):self.comment_num -= 1self.save(update_fields=['comment_num'])class UserAdmin(admin.ModelAdmin):list_display = ('username','email')
#修饰器
然后打开命令行
python manage.py makemigrations
python manage.py migrate
这便生成了sqlite数据库文件
通过sqliteStudio打开浏览:
在views.py文件里编写登录逻辑
def login(request):if request.method == 'POST':user_name = request.POST.get('username','')pass_word = request.POST.get('password','')user = User.objects.filter(username=user_name) #查看数据库里是否有该用户名if user:#如果存在user = User.objects.get(username = user_name)#读取该用户信息if pass_word==user.password:#检查密码是否匹配request.session['IS_LOGIN'] = Truerequest.session['nickname'] = user.nicknamerequest.session['username'] = user_namereturn render(request,'index.html',{'user':user})else:return render(request,'login.html',{'error': '密码错误!'})else:return render(request, 'login.html', {'error': '用户名不存在!'})else:return render(request,'login.html')
因为我们需要记录cookies,所以我们打开settings.py文件,注释该语句
此时登录功能已经实现了。登录成功我们希望页面进行跳转,所以我们需要新建一个index.html
{% load static %}
<html lang="zh"><head><meta charset="utf-8"><title>首页-Ericamblog</title><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="author" content="Ericam_"><!-- CSS --><link rel="shortcut icon" href="{% static 'images/gt_favicon.png' %}"><link rel="stylesheet" media="screen" href="http://fonts.googleapis.com/css?family=Open+Sans:300,400,700"><link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"><link rel="stylesheet" href="{% static 'css/font-awesome.min.css' %}"><!-- Custom styles for our template --><link rel="stylesheet" href="{% static 'css/bootstrap-theme.css'%}" media="screen" ><link rel="stylesheet" href="{% static 'css/blog.css' %}"><link rel="stylesheet" href="{% static 'css/log.css' %}">
</head><body class="back"><script src = "E:/bootstrap/bootstrap-3.3.7-dist/bootstrap-3.3.7-dist/js/jquery.min.js"></script><!--导航栏--><div class="navbar navbar-inverse navbar-fixed-top headroom" ><div class="container"><div class="container-fluid"><div class="navbar-header"><!-- Button for smallest screens --><button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"><span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button><a class="navbar-brand"><img src="{%static 'css/images/lo.png'%}" alt="Progressus HTML5 template"></a></div><ul class="nav navbar-nav navbar-right"><li><a><font size="4" color="white">{{user.nickname}}</font></a></li><li><a href="{%url 'index_unlog'%}"><i class="fa fa-sighout"></i><font size="4">注销</font></a></li></ul></div></div>
</div><center><div class="container"style="padding-top:300px;min-height:800px"><div class="row">,.<p class="lead"><font color="white"">Easy-Download,这里有好多好多资源喔,尽情的享用吧(〃'▽'〃)</font></p><p class="tagline"><font color="white">如果您有优秀的资源,欢迎投递哦</font></p><p><a class="btn btn-action btn-lg" role="button" href="#">START NOW</a></p></div></div></center><footer id="footer" class="top-space"><div class="footer2"><div class="container"><p class="text-center">Copyright © 2020, Ericamblog</p></div></div></footer>
</body>
</html>
views.py
def logsuccess(request):return render(request,'index.html')
添加路由信息
urlpatterns = [path('admin/', admin.site.urls),path('blog/',include('blog.urls')),path('',views.index_unlog,name='index_unlog'),path('login',views.login,name='login'),path('/log',views.logsuccess,name='login-success')
]
手动在数据库中添加一个用户信息
我们进行预览
完成了登录验证功能后,我们就需要添加注册功能,因为刚才用户的信息是我们手动在数据库内添加的,正常情况下应该是前端页面将内容发送给后端,后端经过处理存储在数据库内。
注册模块
(1)views.py
def register(request):if request.method =='POST':user_name = request.POST.get('username','')pass_word_1 = request.POST.get('password_1','')pass_word_2 = request.POST.get('password_2','')nick_name = request.POST.get('nickname','')email = request.POST.get('email','')avatar = request.FILES.get('avatar')if User.objects.filter(username = user_name):return render(request,'register.html',{'error':'用户已存在'})#将表单写入数据库if(pass_word_1 != pass_word_2):return render(request, 'register.html', {'error': '两次密码请输入一致'})user = User()if avatar:user.avatar = 'media/' + user_name + '.png'img = Image.open(avatar)size = img.sizeprint(size)# 因为是要圆形,所以需要正方形的图片r2 = min(size[0], size[1])if size[0] != size[1]:img = img.resize((r2, r2), Image.ANTIALIAS)# 最后生成圆的半径r3 = int(r2/2)img_circle = Image.new('RGBA', (r3 * 2, r3 * 2), (255, 255, 255, 0))pima = img.load() # 像素的访问对象pimb = img_circle.load()r = float(r2 / 2) # 圆心横坐标for i in range(r2):for j in range(r2):lx = abs(i - r) # 到圆心距离的横坐标ly = abs(j - r) # 到圆心距离的纵坐标l = (pow(lx, 2) + pow(ly, 2)) ** 0.5 # 三角函数 半径if l < r3:pimb[i - (r - r3), j - (r - r3)] = pima[i, j]img_circle.save('blog/static/media/'+user_name+'.png')user.username = user_nameuser.password = pass_word_1user.email = emailuser.nickname = nick_nameuser.save()#返回注册成功页面return render(request,'index_unlog.html')else:return render(request,'register.html')
代码含义很好理解,就是将前端提交的信息以user对象存储到数据库中,中间一部分代码是将用户提交的头像切割成圆形(无需理解)
(2)添加路由信息
urlpatterns = [path('admin/', admin.site.urls),path('blog/',include('blog.urls')),path('',views.index_unlog,name='index_unlog'),path('login',views.login,name='login'),path('log',views.logsuccess,name='login-success'),path('register',views.register,name='register')
]
(3)添加register.html
{%load static%}
<!DOCTYPE html>
<html lang="zh-hans">
<head><meta charset="UTF-8"><title>注册</title><link rel="shortcut icon" href="{% static 'images/gt_favicon.png' %}"><link rel="stylesheet" href="{%static 'css/log.css' %}"><link rel="stylesheet" href="{%static 'css/semantic.css' %}">
</head>
<body class="register"><div class="ui center aligned grid"style="margin-top: 200px"><div class="ui six wide column"><h1 class="ui teal header"><font color="black">EricamBlog-用户注册</font></h1><div class="ui segment"><div class="ui content"><form class="ui form" method="post" action="{%url 'register'%}" enctype="multipart/form-data"><div class="field"><input type="text" name="username" placeholder="请输入用户名"><br></div><div class="field"><input type="password" name="password_1" placeholder="请输入密码"><br></div><div class="field"><input type="password" name="password_2" placeholder="请确认密码"><br></div><div class="field"><input type="text" name="nickname" placeholder="请输入昵称"><br></div><div class="field"><input type="text" name="email" placeholder="请输入邮箱"><br></div><div>头像<input type="file" name="avatar"></div>{{ error }}<br><button class="ui fluid large teal button" type="submit">注册</button></form></div></div></div></div>
</body>
</html>
现在注册模块已经完成了,但是刚才我们在编写登录页面时没有添加对于注册页面的超链接跳转,现在需要进行添加。
在login.html里修改如下内容:
此时注册功能已经完成,大家可以自行测试。
接下来我们再来添加忘记密码模块。
正常情况下,忘记密码时应该发送邮件给邮箱,邮箱确认后再填写新密码。这里为了简易操作,便忽略。
(1)添加views.py内容
def forget_password(request):if request.method == 'POST':user_name = request.POST.get('username','')email = request.POST.get('email','')user = User.objects.filter(username = user_name)if user:user = User.objects.get(username = user_name)if(user.email == email):request.session['user_name'] = user_namereturn render(request,'reset.html')else:return render(request,'forget.html',{'error':'您的用户名和邮箱不匹配!'})else:return render(request,'forget.html',{'error':'请输入正确的用户名'})else:return render(request,'forget.html')def reset(request):if request.method == 'POST':pass_word1 = request.POST.get('password1','')pass_word2 = request.POST.get('password2','')user_name = request.session['user_name']user = User.objects.get(username = user_name)if pass_word1 == pass_word2:user.password = pass_word1user.save()return render(request,'login.html')else:return render(request,'reset.html', {'error': '两次密码输入不一致!'})else:return render(request,'reset.html')
(2)添加forget.html和reset.html
forget.html
{%load static%}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>忘记密码</title><link rel="stylesheet" href="{%static 'css/log.css' %}"><link rel="stylesheet" href="{%static 'css/semantic.css' %}">
</head>
<body class="forget"><div class="ui center aligned grid"style="margin-top: 200px"><div class="ui six wide column"><h1 class="ui teal header">Ericam blog-忘记密码</h1><div class="ui segment"><div class="ui content"><form class="ui form" method="post" action="{%url 'forget'%}"><div class="field"><input type="text" name="username" placeholder="请输入用户名"><br></div><div class="field"><input type="text" name="email" placeholder="请输入邮箱"><br></div>{{ error }}<br><button class="ui fluid large teal button" type="submit">下一步</button></form></div></div></div></div>
</body>
</html>
reset.html
{%load static%}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>重置密码</title><link rel="shortcut icon" href="{% static 'images/gt_favicon.png' %}"><link rel="stylesheet" href="{%static 'css/semantic.css' %}"><link rel="stylesheet" href="{%static 'css/log.css' %}">
</head>
<body class="reset"><div class="ui center aligned grid"style="margin-top: 200px"><div class="ui six wide column"><h1 class="ui teal header">Ericam blog-重置密码</h1><div class="ui segment"><div class="ui content"><form class="ui form" method="post" action="{%url 'reset'%}"><div class="field"><input type="password" name="password1" placeholder="请输入新密码"><br></div><div class="field"><input type="password" name="password2" placeholder="请确认新密码"><br></div>{{ error }}<br><button class="ui fluid large teal button" type="submit">确认修改</button></form></div></div></div></div>
</body>
</html>
(3)添加路由
urlpatterns = [path('admin/', admin.site.urls),path('blog/',include('blog.urls')),path('',views.index_unlog,name='index_unlog'),path('login',views.login,name='login'),path('log',views.logsuccess,name='login-success'),path('register',views.register,name='register'),path('forget',views.forget_password,name='forget'),path('reset',views.reset,name='reset')
]
到了这里忘记密码功能已经完成,最后我们还需要添加一下超链接跳转
打开login.html文件,修改:
【至此,登录子系统已经全部完成】
后台美化
django默认自带后台管理系统
创建一个超级管理员账户:
python manage.py createsuperuser
访问:http://127.0.0.1:8000/admin/
接下来我们对后台进行美化
pip install django-simpleui
pip install django_summernote
然后在settings.py添加:
INSTALLED_APPS = ["simpleui", #添加内容,一定要加在admin前'django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','blog','django_summernote'#后台富文本
]SUMMERNOTE_CONFIG = {# Using SummernoteWidget - iframe mode'iframe': True, # or set False to use SummernoteInplaceWidget - no iframe mode# Using Summernote Air-mode'airMode': False,# Use native HTML tags (`<b>`, `<i>`, ...) instead of style attributes'styleWithSpan': False,# Change editor size'width': '80%','height': '480',# Use proper language setting automatically (default)'lang': 'zh-CN',
}
刷新,重新进入admin页面:
给后台添加注册,方便管理数据内容:
修改admin.py文件
from django.contrib import admin
from blog.models import Article,User,Category,Tag,ArticleComment,Message
from django_summernote.admin import SummernoteModelAdmin# Register your models here.
class PostAdmin(SummernoteModelAdmin):summernote_fields = ('content') # 给content字段添加富文本list_display = ['article_id', 'title', 'created_time']search_fields = ['title'] # 搜索框list_filter = ['created_time'] # 过滤器#ass ArticleAdmin(admin.ModelAdmin):
class CommentAdmin(admin.ModelAdmin):list_display = ['username', 'body', 'title']search_fields = ['title'] # 搜索框admin.site.register(Article, PostAdmin)
admin.site.register(Category)
admin.site.register(Tag)
admin.site.register(User)
admin.site.register(ArticleComment,CommentAdmin)
修改models.py文件(完整版):
from django.db import models
from django.contrib import admin
from django.urls import reverse
from django.utils.timezone import now#---------------------------------用户---------------------------------------
class User(models.Model):username = models.CharField(max_length = 50)password = models.CharField(max_length = 200)nickname = models.CharField(max_length = 50,default='匿名')email = models.EmailField()created_time = models.CharField(max_length=50,default=now)comment_num = models.PositiveIntegerField(verbose_name='评论数', default=0) #评论数avatar = models.ImageField(upload_to = 'media', default="media/default.png") #用户头像def __str__(self):return self.usernamedef comment(self):self.comment_num += 1self.save(update_fields=['comment_num'])def comment_del(self):self.comment_num -= 1self.save(update_fields=['comment_num'])#---------------------------------文章评论---------------------------------------
class ArticleComment(models.Model):body = models.TextField()username = models.CharField(max_length=50)userimg = models.CharField(max_length=70)nickname = models.CharField(max_length=50,default="匿名")createtime = models.DateTimeField(verbose_name='创建时间', default=now)article = models.CharField(max_length=50)title = models.CharField(max_length=50)# 使对象在后台显示更友好def __str__(self):return self.articleclass Meta:ordering = ['-createtime']verbose_name = '评论' # 指定后台显示模型名称verbose_name_plural = '评论列表' # 指定后台显示模型复数名称db_table = "comment" # 数据库表名list_display = ('article', 'body')#---------------------------------博客文章标签---------------------------------------
class Tag(models.Model):name = models.CharField(verbose_name='标签名', max_length=64)# 使对象在后台显示更友好def __str__(self):return self.nameclass Meta:ordering = ['name']verbose_name = '标签名称' # 指定后台显示模型名称verbose_name_plural = '标签列表' # 指定后台显示模型复数名称db_table = "tag" # 数据库表名#---------------------------------博客文章分类---------------------------------------
class Category(models.Model):name = models.CharField(verbose_name='类别名称', max_length=64)class Meta:ordering = ['name']verbose_name = "类别名称"verbose_name_plural = '分类列表'db_table = "category" # 数据库表名# 使对象在后台显示更友好def __str__(self):return self.name#---------------------------------博客文章---------------------------------------
class Article(models.Model):STATUS_CHOICES = (('d', '草稿'),('p', '发表'),)article_id = models.CharField(verbose_name='标号', max_length=100)title = models.CharField(verbose_name='标题', max_length=100)content = models.TextField(verbose_name='正文', blank=True, null=True)status = models.CharField(verbose_name='状态', max_length=1, choices=STATUS_CHOICES, default='p')views = models.PositiveIntegerField(verbose_name='浏览量', default=0)created_time = models.DateTimeField(verbose_name='创建时间', default=now)category = models.ForeignKey(Category, verbose_name='分类', on_delete=models.CASCADE, blank=False, null=False)tags = models.ManyToManyField(Tag, verbose_name='标签集合', blank=True)# 使对象在后台显示更友好def __str__(self):return self.title# 更新浏览量def viewed(self):self.views += 1self.save(update_fields=['views'])# 下一篇def next_article(self): # id比当前id大,状态为已发布,发布时间不为空return Article.objects.filter(id__gt=self.id, status='p', pub_time__isnull=False).first()# 前一篇def prev_article(self): # id比当前id小,状态为已发布,发布时间不为空return Article.objects.filter(id__lt=self.id, status='p', pub_time__isnull=False).first()class Meta:ordering = ['-created_time'] # 按文章创建日期降序verbose_name = '文章' # 指定后台显示模型名称verbose_name_plural = '文章列表' # 指定后台显示模型复数名称db_table = 'article' # 数据库表名get_latest_by = 'created_time'
记得使用python manage.py migrate进行生成数据库文件。
此时访问后台:
写文章时富文本工具也加载了出来:
完整项目获取
重构了代码,同时更新了博客内容,关键难点已经写下来了。
如果有问题欢迎在评论区提问。
如果想要获取完整项目,请扫码赞助该项目。
获取方式:扫码赞助9.9,留言邮箱地址。
尾言
其他子模块和该模块大同小异,暂时就不写了。
其中评论提交和删除采取的是ajax交互形式。
如果大家看了觉得有帮助请点赞,为了大家重新写了这篇文章,同时重构了代码,确保一定能跑通。
django开发个人博客系统相关推荐
- 零基础Django3小时开发个人博客系统
准备阶段 Python>=3.5 Django==2.0 Pycharm IDE Python安装 官网下载Python对应版本的安装包(Python3.7.7 For Windows) 双击安 ...
- Django实现简单博客系统
Django实现简单博客系统 第一节 - 基础 1. 简单的导览图,学会不迷路 2. 基本操作介绍 3. 命令简单介绍 4. mysite:所建项目的管理功能目录 5. blog:我们创建的项目之一 ...
- 妙味课堂ajax教程,前后端高级实战 | Node.js 实战开发:博客系统【妙味课堂】
第一部分:Node.js基础视频内容 1-初识NodeJs 2-webstorm的使用 3-Node和JS的异同 4-模块的使用 5-模块加载机制 6-模块-module和exports 7-glob ...
- 博客后台和首页php,基于ThinkPHP5.1+Bootstrap框架开发的博客系统和后台权限管理系统...
源码介绍 基于ThinkPHP5.1+Bootstrap框架开发的博客系统和后台开发框架,主要是基于最新的inkPHP5.1.9框架作为底层开发核心,前端采用Bootstrap框架实现界面响应式设计, ...
- Django完整的开发一个博客系统
今天花了一些时间搭了一个博客系统,虽然并没有相关于界面的美化,但是发布是没问题的. 开发环境 操作系统:windows 7 64位 Django: 1.96 Python:2.7.11 IDE: Py ...
- python 毕业设计 源码 博客_blogs: 仅供学习参考使用,Python Django毕业设计——个人博客系统...
大学毕业设计个人Blog博客系统 基于"python3.6.5"和"Django2"开发的的个人博客系统. 层级结构 cd bbs; tree . ├── bb ...
- Django实现的博客系统中使用富文本编辑器ckeditor
操作系统为OS X 10.9.2,Django为1.6.5. 1.下载和安装 1.1 安装 ckeditor 下载地址 https://github.com/shaunsephton/django-c ...
- halo java_Halo - 轻快,简洁,功能强大,使用Spring Boot开发的博客系统
Halo 是一款现代化的个人独立博客系统,给习惯写博客的同学多一个选择. 简介 Halo [ˈheɪloʊ],意为光环.当然,你也可以当成拼音读(哈喽). 一个优秀的开源博客发布应用,值得一试. 声明 ...
- Django开发个人博客网站——1、开发环境
1.写在前面的话 刚最开始自学python,然后学习django框架,中间断断续续有几个月的时间,是时候通过一个项目来检验下自己的学习成果了.既然学习了django web框架,那很自然的就是想到要搭 ...
- Django开发个人博客网站——19、通过Django Haystack实现搜索功能(上)
该博客最开始采用的模板是并不包括搜索功能的,在主页只有主页.归档和分类三个部分.最后博主自己添加了搜索框,不过其实不太想让大家使用这个功能,因此将搜索框隐藏了,只有再点击搜索时,才会显现出来.但是这个 ...
最新文章
- 30个Python常用极简代码,拿走就用
- pycharm使用Djiago创建第一个web项目
- 大规模集群自动化部署SSH无密码登陆
- java linux urlencode_iOS urlEncode编码解码(非过时方法,已解决)
- matlab中 三种方法计算 Ax b,在MATLAB中,方程Ax=B的解可以用哪个命令求得? matlab 求助 解方程组...
- 本年度最成功科技IPO企业之一:Twilio股票一月暴涨167%
- sublime编写python路径报错怎么改_sublime开发Python的编码问题
- 会话管理:Session与Cookie
- 评估微型计算机的主要指标,微型计算机的工作过程和主要性能指标.doc
- 四川大学计算机学院 期末考试安排,四川大学《计算机组成原理》2018期末考试B卷.doc...
- 图解MySQL5.5详细安装与配置过程
- CentOS下gitlab迁移和升级
- 【面向对象】DDD(一):传统开发模式 VS DDD 开发模式
- PDM系统服务器管理,PDM产品数据管理系统
- 百度地图获取经纬度的方式
- 凝视联通4G和4G+战略落地半年报,从数据亮点中找出路
- 【渝粤题库】广东开放大学 企业财务报表分析 形成性考核
- Java 合并、拆分PDF文档
- 服务器突然断电文件系统损坏,电脑突然断电造成系统文件损坏该如何修复?(高级篇)...
- 能煮熟鸡蛋的慢 SQL!阿里巴巴数据中心的“煮蛋史”!
热门文章
- TCP长连接开发相关,调试工具SocketTool与框架GatewayWorker
- VB基础入门教程.doc
- javascript/js计算器的基础制作
- MATLAB实现SVM多分类(one-vs-rest),利用自带函数fitcsvm
- UTrust4701F双界面NFC读写器读卡器测试软件读写NFC电子标签的文本|网址|电子名片|智能海报|蓝牙地址内容操作说明
- 典型ieee3机9节点电力系统潮流分析_【最新学术进展】清华大学电机系牵头研究推出高比例可再生能源电力系统标准测试系统HRP38...
- 记一次曲折的获取权限
- 验证软件包的数字签名
- 怎么将PDF文件在线转换成JPG图片
- w10系统打印服务器怎样出来,win10怎么打开关闭打印机服务教程步骤