---title: 博客项目(Django版)项目tags: Djangonotebook: 7.0第五月 Python_web后端---[toc]# 一、项目概述## 项目运行环境1. Python3.6+2. Django 1.113. MySQL 5.74. 其他插件(图片处理、分页、验证码....)## 项目详细功能介绍### 前台功能1. 项目首页展示2. 轮播图3. 博客推荐4. 最新发布5. 博客分类6. 最新评论文章7. widgets小插件8. 搜索功能9. 博客分类功能10. 博客标签查询11. 友情链接12. 博客分页功能13. 博客详细14. 最新评论文章15. 发表评论16. 评论展示17. 评论数18. 阅读数19. 登录功能20. 注册功能21. 邮箱验证功能22. 注销功能23. 页面模板24. 标签云功能25. 读者墙功能### 后台功能1. 用户维护2. 权限管理3. 博客分类维护4. 标签维护5. 友情链接6. 轮播图维护### 项目演示项目演示### 项目代码演示代码展示# 二、开发环境搭建> 使用virtualenv 和 virtualenwrapper1. MySQL 5.7```vimsudo apt install mysql-server mysql-client```2. 安装mysql驱动```vimpip install pymysql```3. 安装Django```vimpip install django==1.11```# 三、创建项目## 创建项目和应用- 创建项目```vimdjango-admin startproject django-blog```- 创建应用```vimpython manage.py startapp userapppython manage.py startapp blogapp```## 配置数据库- 在settings中配置数据库```pythonDATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django_blog_db', 'USER': 'root', 'PASSWORD': 'wwy123', 'HOST': '127.0.0.1', 'PORT': '3306', }}```## 创建数据库(执行迁移文件)```pythonpython manage.py migrate```## 创建超级管理员```pythonpython manage.py createsuperuser```# 四、创建数据模型## USERAPP### USER(用户模型)```djangofrom django.contrib.auth.models import AbstractUserclass BlogUser(AbstractUser): nikename = models.CharField('昵称', max_length=20, default='')```> 提示:需要在settings配置文件中设置:AUTH_USER_MODEL = 'users.BlogUser'### EMAIL(邮箱验证数据模型)```djangoclass EmailVerifyRecord(models.Model): code = models.CharField(verbose_name='验证码', max_length=50,default='') email = models.EmailField(max_length=50, verbose_name="邮箱") send_type = models.CharField(verbose_name="验证码类型", choices=(("register",u"注册"),("forget","找回密码"), ("update_email","修改邮箱")), max_length=30) send_time = models.DateTimeField(verbose_name="发送时间", default=datetime.now) class Meta: verbose_name = "邮箱验证码" # 复数 verbose_name_plural = verbose_name def __str__(self): return '{0}({1})'.format(self.code, self.email)```## BLOGAPP### Banner(轮播图模型)```djangoclass Banner(models.Model): title = models.CharField('标题', max_length=50) cover = models.ImageField('轮播图', upload_to='static/images/banner') link_url = models.URLField('图片链接', max_length=100) idx = models.IntegerField('索引') is_active = models.BooleanField('是否是active', default=False) def __str__(self): return self.title class Meta: verbose_name = '轮播图' verbose_name_plural = '轮播图'```### Category(博客分类模型)```djangoclass BlogCategory(models.Model): name = models.CharField('分类名称', max_length=20, default='') class Meta: verbose_name = '博客分类' verbose_name_plural = '博客分类' def __str__(self): return self.name```### Tags(标签模型)```djangoclass Tags(models.Model): name = models.CharField('标签名称', max_length=20, default='') class Meta: verbose_name = '标签' verbose_name_plural = '标签' def __str__(self): return self.name```### Blog(博客模型)```djangoclass Post(models.Model): user = models.ForeignKey(BlogUser, verbose_name='作者') category = models.ForeignKey(BlogCategory, verbose_name='博客分类', default=None) tags = models.ManyToManyField(Tags, verbose_name='标签') title = models.CharField('标题', max_length=50) content = models.TextField('内容') pub_date = models.DateTimeField('发布日期', default=datetime.now) cover = models.ImageField('博客封面', upload_to='static/images/post', default=None) views = models.IntegerField('浏览数', default=0) recommend = models.BooleanField('推荐博客', default=False) def __str__(self): return self.title class Meta: verbose_name = '博客' verbose_name_plural = '博客'```### Comment(评论模型)```djangoclass Comment(models.Model): post = models.ForeignKey(Post, verbose_name='博客') user = models.ForeignKey(BlogUser, verbose_name='作者') pub_date = models.DateTimeField('发布时间') content = models.TextField('内容') def __str__(self): return self.content class Meta: verbose_name = '评论' verbose_name_plural = '评论'```### FriendlyLink(友情链接模型)```djangoclass FriendlyLink(models.Model): title = models.CharField('标题', max_length=50) link = models.URLField('链接', max_length=50, default='') def __str__(self): return self.title class Meta: verbose_name = '友情链接' verbose_name_plural = '友情链接'```# 五、实现首页页面模板## 创建模板文件夹> 创建模板文件templates,并在settings.py中设置```djangoTEMPLATES = [ { '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', ], }, },]```## 配置静态文件路径```djangoSTATIC_URL = '/static/'STATICFILES_DIRS = ( os.path.join(BASE_DIR, "static"),)```# 六、创建首页路由- 创建视图函数```djangodef index(request): return render(request, 'index.html', {})```- 配置url```djangourl(r'^$', index, name='index' )```- 修改模板CSS JS等静态文件的路径# 七、实现幻灯片功能(Banner)- 注册模型```djangofrom blogs.models import Banneradmin.site.register(Banner)```- 编写views```djangofrom .models import Bannerdef index(request): banner_list = Banner.objects.all() ctx = { 'banner_list': banner_list, } return render(request, 'index.html', ctx)```- 模板```django
{% for banner in banner_list %} {% if banner.is_active %}
{% else %}
{% endif %} {% endfor %}
{% for banner in banner_list %} {% if banner.is_active %}
{% else %}
{% endif %} {% endfor %}
```# 八、实现博客推荐- 注册模型```djangofrom blogs.models import Banner,Post,BlogCategory,Tags...admin.site.register(BlogCategory)admin.site.register(Tags)admin.site.register(Post)```- 编写views```django# 视图函数 HTTPRequestdef index(request): banner_list = Banner.objects.all() recommend_list = Post.objects.filter(recommend=1) ctx = { 'banner_list': banner_list, 'recommend_list': recommend_list, } return render(request, 'index.html', ctx)```- 模板```html {% for post in recommend_list %}
【推荐】{{post.title}}
{{post.content}}
{% endfor %} ```# 九、实现最新发布- 编写views```django# 视图函数 HTTPRequestdef index(request): ... post_list = Post.objects.order_by('-pub_date').all()[:10] .... ctx = { 'banner_list': banner_list, 'recommend_list': recommend_list, 'post_list': post_list, } return render(request, 'index.html', ctx)```- 模板```django {% for post in post_list%}
{{post.pub_date|date:'Y-m-d'}}{{post.views}}{{post.comment_set.count}}
{% autoescape off %}
{{post.content | truncatechars_html:200}}
{% endautoescape %}
{% endfor %} ```# 十、实现博客分类功能- 编写视图```django# 视图函数 HTTPRequestdef index(request): banner_list = Banner.objects.all() recommend_list = Post.objects.filter(recommend=1) post_list = Post.objects.order_by('-pub_date').all()[:10] blogcategory_list = BlogCategory.objects.all() ctx = { 'banner_list': banner_list, 'recommend_list': recommend_list, 'post_list': post_list, 'blogcategory_list': blogcategory_list, } return render(request, 'index.html', ctx)```- 模型```html
最新发布
{%for c in blogcategory_list%}{{c.name}}{% endfor %}
```# 十一、实现最新评论功能- 编写views```django
{% for post in new_comment_list %}
{{ post.title }} {{ post.pub_date }}
{{ post.views }}
{% endfor %}
```# 十二、实现搜索功能- 编写views```djangofrom django.views.generic.base import Viewfrom django.db.models import Qclass SearchView(View): # def get(self, request): # pass def post(self, request): kw = request.POST.get('keyword') post_list = Post.objects.filter(Q(title__icontains=kw)|Q(content__icontains=kw)) ctx = { 'post_list': post_list } return render(request, 'list.html', ctx)```- urls```djangourl(r'^search$', SearchView.as_view(), name='search'),```# 十三、实现友情链接- 编写视图 (数据源)```djangodef index(request): .... friendlylink_list = FriendlyLink.objects.all() .....```- 模板```django
友情链接
{% for friendlylink in friendlylink_list %}{{ friendlylink.title }}{% endfor %}
```# 十四、实现博客列表功能- 编写views```djangodef blog_list(request): post_list = POST.objects.all() ctx = { 'post_list': post_list, } return render(request, 'list.html', ctx)```- 编写路由```djangourl(r'^list$', blog_list, name='blog_list'),```- base.html```html
爱学习 更爱分享
{% if user.is_authenticated %}
{% else %}
{% endif %}
{% block content %}{% endblock %}
Copyright © 2016.Company name All rights reserved.
```# 十五、实现分页功能- 安装包```djangopip install django-pure-pagination```> 参考链接: https://github.com/jamespacileo/django-pure-pagination```djangodef blog_list(request): post_list = Post.objects.all() try: page = request.GET.get('page', 1) except PageNotAnInteger: page = 1 p = Paginator(post_list, per_page=1, request=request) post_list = p.page(page) ctx = { 'post_list': post_list, } return render(request, 'list.html', ctx)```- 模板```django
博客列表
{% for post in post_list.object_list %}
{{post.pub_date|date:'Y-m-d'}} {{post.views}}{{post.comment_set.count}}
{{post.content}}
{% endfor %} {% include "_pagination.html" %}```- _pagination.html```django{% load i18n %}
{% if post_list.has_previous %}‹‹ 上一页{% else %}‹‹ 上一页{% endif %} {% for page in post_list.pages %} {% if page %} {% ifequal page post_list.number %}{{ page }}{% else %}{{ page }}{% endifequal %} {% else %} ... {% endif %} {% endfor %} {% if post_list.has_next %}下一页 ››{% else %}下一页 ››{% endif %}
```# 十六、实现标签云功能```djangodef blog_list(request): post_list = Post.objects.all() try: page = request.GET.get('page', 1) except PageNotAnInteger: page = 1 p = Paginator(post_list, per_page=1, request=request) post_list = p.page(page) tags = Tags.objects.all() tag_message_list = [] for t in tags: count = len(t.post_set.all()) tm = TagMessage(t.id, t.name, count) tag_message_list.append(tm) ctx = { 'post_list': post_list, 'tags': tag_message_list } return render(request, 'list.html', ctx)```- 模板```html
标签云
{% for t in tags %}
{% endfor %}
```# 十七、实现分类查询功能- 编写视图```djangodef blog_list(request, cid=-1): post_list = None if cid != -1: cat = BlogCategory.objects.get(id=cid) post_list = cat.post_set.all() else: post_list = Post.objects.all() .... ctx = { 'post_list': post_list, 'tags': tag_message_list } return render(request, 'list.html', ctx)```- 编写路由```djangourl(r'^category/(?P[0-9]+)/$', blog_list),```- 模板 index```html
最新发布
{%for c in blogcategory_list%}{{c.name}}{% endfor %}
```# 十八、实现按标签查询功能- 编写views```djangodef blog_list(request, cid=-1, tid=-1): post_list = None if cid != -1: cat = BlogCategory.objects.get(id=cid) post_list = cat.post_set.all() elif tid != -1: tag = Tags.objects.get(id=tid) post_list = tag.post_set.all() else: post_list = Post.objects.all() .... ctx = { 'post_list': post_list, 'tags': tag_message_list } return render(request, 'list.html', ctx)```- 路由设置```djangourl(r'^tags/(?P[0-9]+)/$', blog_list),```- 模板```django
标签云
{% for t in tags %}
{% endfor %}
```# 十九、实现博客详情功能- 定义视图函数```pythondef blog_detail(request,bid): post = Post.objects.get(id=bid) post.views = post.views + 1 post.save() # 博客标签 tag_list = post.tags.all() ctx = { 'post': post, } return render(request, 'show.html', ctx)```- 路由设置```pythonurl(r'^blog/(?P[0-9]+)/$', blog_detail, name='blog_detail'),```- 前端展示```html{% extends 'base.html' %}{% block title %}知奇博客-详细 {% endblock %}{% block content %}
{{post.pub_date|date:'Y-m-d'}} {{post.user.username}}{{post.category.name}} {{post.views}}
{{post.content}}
标签: {% for tag in post.tags.all %}{{tag.name}}{% endfor %}
{% endblock %}```# 二十、实现相关推荐功能- 编写视图```djangodef blog_detail(request, pid): post = Post.objects.get(id=pid) post.views = post.views + 1 post.save() comment_list = Comment.objects.order_by('-pub_date') # 最新评论的博客 列表 new_comment_list = [] # 去重 for c in comment_list: if c.post not in new_comment_list: new_comment_list.append(c.post) # 相关推荐 # 首先 我们需要取到 这篇文章的tag tag_post_list = [] for tag in post.tags.all(): tag_post_list.extend(tag.post_set.all()) ctx = { 'post': post, 'new_comment_list': new_comment_list, 'tag_post_list': tag_post_list } return render(request, 'show.html', ctx)```- 模板```html {% for tag_post in tag_post_list %}
{% endfor %}```# 二十一、实现发表评论的功能# 二十二、实现评论列表功能# 二十三、实现登录功能# 二十四、实现注册功能# 二十五、实现注册验证功能# 二十六、实现注销功能# 二十七、实现后台富文本功能