使用django + KindEditor 开发个人博客系统
前奏小知识
1. 通过url参数组合不同的过滤条件
django框架部分
1. 数据结构models
- from django.db import models
- # Create your models here.
- # 大分类表
- class Category(models.Model):
- caption = models.CharField(max_length=32)
- # 文章类型表
- class ArticleTyp(models.Model):
- caption = models.CharField(max_length=32)
- # 创建一个文章表,设置标题和内容;文章大分类小分类 四个字段
- class Article(models.Model):
- title = models.CharField(max_length=1024)
- content = models.CharField(max_length=30720)
- category = models.ForeignKey(Category, null=True, on_delete=models.SET_NULL)
- article_type = models.ForeignKey(ArticleTyp, null=True, on_delete=models.SET_NULL)
- # 测试使用内存级别选项,不存储于数据库
- # type_choice = (
- # (1, "Python"),
- # (2, "JavaScript"),
- # (3, "前端"),
- # )
- # article_type_id = models.IntegerField(choices=type_choice)
2. url
- url(r'^article/-(?P<article_type_id>\d+)-(?P<category_id>\d+).html', blog_views.Article.as_view()),
3.views
- from django.shortcuts import render
- from django.views import View
- from Blog import models
- # Create your views here.
- class Article(View):
- def get(self, request, *args, **kwargs):
- # 查询时的过滤条件
- condition = {}
- for k, v in kwargs.items():
- # 渲染html文件中判断是否为选中分类:url参数为字符串;数据库查询出来的id为int类型
- # 转换为同一个类型,渲染模板时做比较
- kwargs[k] = int(v)
- if v == '0': # 如果为零,查询条件中就不传入此参数
- pass
- else:
- condition[k] = v
- print(condition)
- article_type_list = models.ArticleTyp.objects.all()
- # models 中使用内存级别字段
- # article_type_list = models.Article.type_choice
- category_list = models.Category.objects.all()
- result = models.Article.objects.filter(**condition)
- return render(
- request,
- # 'blog/article.html',
- 'blog/article_simple_tag.html',
- {'article_type_list': article_type_list,
- 'category_list': category_list,
- 'articles': result,
- 'condition_dict': kwargs}
- )
4. models 数据库类型核对
- from django.db import models
- # Create your models here.
- # 大分类表
- class Category(models.Model):
- caption = models.CharField(max_length=32)
- # 文章类型表
- class ArticleTyp(models.Model):
- caption = models.CharField(max_length=32)
- # 创建一个文章表,设置标题和内容;文章大分类小分类 四个字段
- class Article(models.Model):
- title = models.CharField(max_length=1024)
- content = models.CharField(max_length=30720)
- category = models.ForeignKey(Category, null=True, on_delete=models.SET_NULL)
- article_type = models.ForeignKey(ArticleTyp, null=True, on_delete=models.SET_NULL)
- # 测试使用内存级别选项,不存储于数据库
- # type_choice = (
- # (1, "Python"),
- # (2, "JavaScript"),
- # (3, "前端"),
- # )
- # article_type_id = models.IntegerField(choices=type_choice)
5.自定义html模板 函数 生成过滤项的a 标签html字符串
templatetags/condition_filter.py
- #!/usr/bin/env python3
- # -*- coding:utf-8 -*-
- # @Time: 2020/8/8 11:17
- # @Author:zhangmingda
- # @File: condition_filter.py
- # @Software: PyCharm
- # Description:
- from django import template
- from django.utils.safestring import mark_safe
- register = template.Library()
- @register.simple_tag
- def filter_all(condition_dict, all_condition):
- article_type_id = condition_dict["article_type_id"]
- category_id = condition_dict["category_id"]
- all_ret = ""
- if all_condition == "article_type_id":
- if article_type_id == 0:
- all_ret = '<a href="/article/-0-%s.html" class="condition active">全部</a>' % category_id
- else:
- all_ret = '<a href="/article/-0-%s.html" class="condition ">全部</a>' % category_id
- if all_condition == "category_id":
- if category_id == 0:
- all_ret = '<a href="/article/-%s-0.html" class="condition active">全部</a>' % article_type_id
- else:
- all_ret = '<a href="/article/-%s-0.html" class="condition ">全部</a>' % article_type_id
- all_ret = mark_safe(all_ret)
- return all_ret
- @register.simple_tag
- def filter_article_type(condition_dict, article_type_list ):
- """
- {% if condition_dict.article_type_id == article_type.id %}
- <a href="/article/-{{ article_type.id }}-{{ condition_dict.category_id }}.html" class="condition active">{{ article_type.caption }}</a>
- {% else %}
- <a href="/article/-{{ article_type.id }}-{{ condition_dict.category_id }}.html" class="condition">{{ article_type.caption }}</a>
- {% endif %}
- :return:
- """
- a_tag_list = []
- for article_type in article_type_list:
- article_type_id = article_type.id
- # models 中使用内存级别字段
- # article_type_id = article_type[0]
- if condition_dict["article_type_id"] == article_type_id:
- ret = '<a href="/article/-{article_type_id}-{category_id}.html" class="condition active">{article_type_caption}</a>'.format(
- article_type_id=article_type_id,
- category_id=condition_dict.get('category_id'),
- article_type_caption=article_type.caption,
- # models 中使用内存级别字段
- # article_type_caption=article_type[1]
- )
- else:
- ret = '<a href="/article/-{article_type_id}-{category_id}.html" class="condition ">{article_type_caption}</a>'.format(
- article_type_id=article_type_id,
- category_id=condition_dict.get('category_id'),
- article_type_caption=article_type.caption,
- # models 中使用内存级别字段
- # article_type_caption=article_type[1]
- )
- a_tag_list.append(ret)
- all_a_tag = ''.join(a_tag_list)
- return mark_safe(all_a_tag)
- @register.simple_tag
- def filter_category(condition_dict, category_list ):
- """
- {% for category in category_list %}
- {% if condition_dict.category_id == category.id %}
- <a href="/article/-{{ condition_dict.article_type_id }}-{{ category.id }}.html" class="condition active" >{{ category.caption }}</a>
- {% else %}
- <a href="/article/-{{ condition_dict.article_type_id }}-{{ category.id }}.html" class="condition" >{{ category.caption }}</a>
- {% endif %}
- {% endfor %}
- :param condition_dict:
- :param category_list:
- :return:
- """
- filter_category_tag_list = []
- for category in category_list:
- category_id = category.id
- if condition_dict.get("category_id") == category_id:
- category_a_tag = '<a href="/article/-%s-%s.html" class="condition active" >%s</a>' % (condition_dict.get("article_type_id"), category_id, category.caption )
- else:
- category_a_tag = '<a href="/article/-%s-%s.html" class="condition " >%s</a>' % (condition_dict.get("article_type_id"), category_id, category.caption )
- filter_category_tag_list.append(category_a_tag)
- ret = ''.join(filter_category_tag_list)
- return mark_safe(ret)
7.html 加载自定义模板方法
- {% load condition_filter %}
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <style>
- .condition{
- display: inline-block;
- border: 1px solid #dddddd;
- padding: 3px 5px;
- margin: 5px;
- }
- .condition.active {
- background-color: #843534;
- }
- </style>
- </head>
- <body>
- <h1>过滤条件</h1>
- <div>
- <!--使用simpletag自定义函数生成HTML标签-->
- {% filter_all condition_dict "article_type_id" %}
- {% filter_article_type condition_dict article_type_list %}
- </div>
- <div>
- <!--使用simpletag自定义函数生成HTML标签-->
- {% filter_all condition_dict "category_id" %}
- {% filter_category condition_dict category_list %}
- </div>
- <h1>查询结果</h1>
- <ul>
- {% for article in articles %}
- <li> {{ article.id }} - {{ article.title }}</li>
- {% endfor %}
- </ul>
- </body>
- </html>
正式来一发
数据库设计
- """
- 用户表:UserInfo
- nid 自增列
- username 用户名 不可重复
- password 密码
- nickname 昵称
- email 邮箱
- avtar 头像
- create_time 创建时间
- fans 粉丝们 ---- 多对多表 外键自己
- 个人博客信息表:Blog
- nid 自增列
- title 个人博客标题
- site 个人博客前缀
- theme 博客主题
- user 博客一对一 对应用户id
- 互粉关系表:UserFans
- user 博主 外键到用户表
- folower 粉丝 外键到用户表
- class Meta: 不可重复
- unique_together = [('user', 'follower')]
- 文章分类表(博主个人):Category
- nid 自增
- title 标题
- blog 所属博客 -- 外键到博客表
- 文章标签表:Tag
- nid 自增主键
- title 标签名称
- blog 所属博客 - 外键到博客表-主键
- 文章内容表:ArticleDetail
- content 文章内容
- aritcle 所属文章 - 外键到文章信息表
- 顶/踩 统计:UpDown
- aritcle 对应文章 - 外键到 文章表的主键
- user 用户 外键到用户表主键
- up 顶或者是踩:布尔值即可
- class Meta: # 两个字段合并唯一 :顶或者踩,一篇文章只能顶或者踩一次
- unique_together = [('article', 'user')]
- 评论表:Comment
- nid 自增主键
- content 内容
- create_time 创建时间
- reply 回复/评论 对自己表中已有的数据:self
- article 被评论的文章 - 外键到文章表主键
- user 评论着 - 外键到用户表 主键
- 文章表:Article
- nid 自增主键
- title 文章标题
- summary 文章简介
- read_count 阅读量
- comment_count 评论数量
- up_count 点赞数量
- down_count 踩量
- create_time 创建时间
- blog 所属博客
- category 文章类型
- type_choices 语言分类选项
- article_type 语言分类
- tags 标签 多对多 指定多对多的第三张表名Article2Tag
- 文章-标签多对多表:Article2Tag
- article 文章 外键到文章表主键
- tag 标签 外键到标签表主键
- class Meta: 标签&文章一起,不得重复
- unique_together = [('article', 'tag')]
- """
数据库表结构代码
models.py
- from django.db import models
- # Create your models here.
- class UserInfo(models.Model):
- """
- 用户表
- """
- uid = models.BigAutoField(primary_key=True)
- username = models.CharField(max_length=32, unique=True, verbose_name="用户名")
- password = models.CharField(verbose_name='密码', max_length=64)
- nickname = models.CharField(verbose_name='昵称', max_length=32)
- email = models.EmailField(verbose_name='邮箱', unique=True)
- avatar = models.ImageField(verbose_name='头像')
- create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
- fans = models.ManyToManyField(verbose_name='粉丝们',
- to='UserInfo',
- through='UserFans',
- through_fields=('user', 'follower'))
- class UserFans(models.Model):
- """互粉关系表"""
- user = models.ForeignKey(verbose_name='博主', to=UserInfo, to_field='uid', related_name='users', on_delete=models.SET_NULL, null=True)
- follower = models.ForeignKey(verbose_name='粉丝', to=UserInfo, to_field='uid', related_name='followers', on_delete=models.SET_NULL, null=True)
- class Meta:
- unique_together = [('user', 'follower')]
- class Blog(models.Model):
- """
- 博客信息
- """
- bid = models.BigIntegerField(primary_key=True)
- title = models.CharField(verbose_name='标题', max_length=128)
- site = models.CharField(verbose_name="个人博客前缀", max_length=32, unique=True)
- theme = models.CharField(verbose_name='博客主题', max_length=32)
- user = models.OneToOneField(to='UserInfo', to_field='uid', on_delete=models.SET_NULL, null=True)
- class Category(models.Model):
- """博主个人文章分类"""
- cid = models.AutoField(primary_key=True)
- title = models.CharField(verbose_name='分类标题', max_length=32)
- blog = models.ForeignKey(verbose_name='所属博客', to='Blog', to_field='bid',
- on_delete=models.SET_NULL,null=True)
- class Tag(models.Model):
- tid = models.AutoField(primary_key=True)
- title = models.CharField(verbose_name='标签名称',max_length=32)
- blog = models.ForeignKey(verbose_name="所属文章",to='Blog', to_field='bid',on_delete=models.SET_NULL,
- null=True)
- class Article(models.Model):
- """文章信息表"""
- aid = models.BigAutoField(primary_key=True)
- title = models.CharField(verbose_name="文章标题", max_length=128)
- summary = models.CharField(verbose_name="文章简介", max_length=255)
- read_count = models.IntegerField(default=0)
- coumment_count = models.IntegerField(default=0)
- up_count = models.IntegerField(default=0)
- down_count = models.IntegerField(default=0)
- create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
- blog = models.ForeignKey(verbose_name="所属博客", to='Blog', to_field='bid',
- on_delete=models.SET_NULL, null=True)
- category = models.ForeignKey(verbose_name='文章类型', to='Category',to_field='cid',
- on_delete=models.SET_NULL, null=True)
- type_choices = [
- (1, "Python"),
- (2, "Linux"),
- (3, "OpenStack"),
- (4, "GoLang"),
- ]
- article_type = models.IntegerField(choices=type_choices, default=None)
- tags = models.ManyToManyField(
- to='Tag', through='ArticleToTag',
- through_fields=('article', 'tag')
- )
- class ArticleToTag(models.Model):
- article = models.ForeignKey(verbose_name='文章', to='Article', to_field='aid',
- on_delete=models.SET_NULL, null=True)
- tag = models.ForeignKey(verbose_name="标签", to='Tag', to_field='tid',
- on_delete=models.SET_NULL,null=True)
- class Meta:
- unique_together = [
- ('article', 'tag')
- ]
- class ArticleDetail(models.Model):
- """文章详情表"""
- content = models.TextField(verbose_name="文章内容")
- article = models.OneToOneField(verbose_name="所属文章", to='Article',to_field='aid',
- on_delete=models.CASCADE)
- class UpDown(models.Model):
- """文章顶/踩"""
- article = models.ForeignKey(verbose_name="文章", to='Article', to_field='aid',
- on_delete=models.CASCADE)
- user = models.ForeignKey(verbose_name='顶踩用户', to='UserInfo', to_field='uid',
- on_delete=models.CASCADE)
- up = models.BooleanField(verbose_name='是/否赞')
- class Meta:
- """联合唯一"""
- unique_together = [('article', 'user')]
- class Comment(models.Model):
- """评论表"""
- nid = models.BigAutoField(primary_key=True)
- content = models.CharField(verbose_name='评论内容', max_length=255)
- create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
- reply = models.ForeignKey(verbose_name="回复已有评论",to="self",
- null=True, on_delete=models.SET_NULL)
- article = models.ForeignKey(verbose_name="对应的文章",
- to="Article",
- to_field='aid',
- on_delete=models.SET_NULL,
- null=True)
创建数据库:python manage.py makemigrations; python manage.py migrate
使用django + KindEditor 开发个人博客系统的更多相关文章
- Django完整的开发一个博客系统
今天花了一些时间搭了一个博客系统,虽然并没有相关于界面的美化,但是发布是没问题的. 开发环境 操作系统:windows 7 64位 Django: 1.96 Python:2.7.11 IDE: Py ...
- Nuxt开发搭建博客系统
nuxt.js第三方插件的使用?路由的配置pages目录自动生成路由layoutsdefault.vueerror.vueVuex的使用权限篇Mysqladvice nuxt.js 追求完美,相信大家 ...
- 转 Django+Bootstrap练习--我的类博客系统开发
转自: http://blog.sina.com.cn/s/blog_7e050dc80102w312.html 本文记录了一个类博客网站从无到有的搭建过程,同时也是我入门django以及再次入门前端 ...
- Django开发个人博客入门学习经验贴
[写在前面] 入门学习搭建个人博客系统首先还是参考大佬们的经验,记得刚入手Django的时候,一篇博客大佬说过一句话,做技术的不要一开始就扎头于细节中,先把握整体框架,了解这个对象之后再去了解细节,进 ...
- nodejs--express开发个人博客(-)
写完了入门笔记,开始进入开发阶段吧.基于上一节的内容,现在着手开发个人博客系统.先划分一下功能吧 /:首页 /login:登陆 /reg:注册 /post:发表文章 /logout:退出 首先规划一下 ...
- 如何快速部署国人开源的 Java 博客系统 Tale
除了闷头专研技术之外,程序员还需要不断地写作进行技术积累,写博客是其中最重要的方式之一.商业博客平台不少,但是更符合程序员背景的方案,是自己开发一个博客平台或者使用开源的博客平台. 开源的博客平台多如 ...
- go语言打造个人博客系统(二)
go语言打造个人博客系统(二) 在上篇文章go语言打造个人博客系统(一)中,我们了解了go语言的优点和go语言的数据库操作,本次我们会完成博客系统的后端开发. 博客系统后端接口开发 路由测试 ht ...
- Halo-个人独立博客系统
项目地址:https://github.com/halo-dev/halo 安装指导:https://halo.run/guide/ 简介: Halo 是一款现代化的个人独立博客系统,给习惯写博客 ...
- 【django之博客系统开发】
一.项目简介 使用django开发一套博客系统,参考博客园. 需求如下: 项目结构: 二.全部代码 from django.db import models # Create your models ...
随机推荐
- Ubuntu 18.04.5 LTS Ceph集群之 cephx 认证及使用普通用户挂载RBD和CephFS
1.cephx认证和授权 1.1 CephX认证机制 Ceph使用cephx协议对客户端进行身份认证: 1.每个MON都可以对客户端进行身份验正并分发密钥, 不存在单点故障和性能瓶颈 2. MON会返 ...
- CF1445E four points
我们不妨枚举四个点的移动方向. 那我们可以直接算出在该情况的最优的答案. #include<iostream> #include<cstdio> #include<alg ...
- Atcoder Grand Contest 002 F - Leftmost Ball(dp)
Atcoder 题面传送门 & 洛谷题面传送门 这道 Cu 的 AGC F 竟然被我自己想出来了!!!((( 首先考虑什么样的序列会被统计入答案.稍微手玩几组数据即可发现,一个颜色序列 \(c ...
- MySQL-数据库多表关联查询太慢,如何进行SQL语句优化
工作中我们经常用到多个left join去关联其他表查询结果,但是随着数据量的增加,一个表的数据达到百万级别后,这种普通的left join查询将非常的耗时. 举个例子: 现在porder表有 10 ...
- 动态滑动登陆框-Html+Css+Js
动态滑动登陆框 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <t ...
- C#多个标题头合并
protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e) { switch (e.Row.RowType) ...
- 日常Java 2021/9/27
题目: 在某个比赛中,有6个评委为参赛的选手打分,分数为1-100的随机整数.选手的最后得分为:除去最高分和最低分后的4个评委分值的平均值(不考虑小数部分). package m; import ja ...
- python格式化输出的两种方式对比
1.%符号方法和format()函数方法 2.对比: 1 print('我今年%d岁' %22.125) 2 print('我今年{0:f}'.format(22.125)) 3 #报错 4 #槽中类 ...
- 【Reverse】初遇花指令
解密花指令 全文参考了一个大师傅的blog:https://blog.csdn.net/zhangmiaoping23/article/details/38400393 介绍 花指令是对抗反汇编的有效 ...
- 转 关于HttpClient,HttpURLConnection,OkHttp的用法
转自:https://www.cnblogs.com/zp-uestc/p/10371012.html 1 HttpClient入门实例 1.1发送get请求 1 2 3 4 5 6 7 8 9 10 ...