一、BBS-个人博客项目完整搭建
 
项目开发流程
一、项目分类
现在互联网公司需要开发的主流web项目一般分为两类:面向互联网用户,和公司内部管理。面向互联网用户: C(consumer)端项目
公司内部管理:B(business)端项目还有一类web应用,基本采用基于角色的权限控制,不同的员工在这套系统中拥有不同的权限,
适用于公司内部管理。基于权限的后台关系系统:RBAC权限管理系统二、项目开发模式分类
最常见的两类为瀑布开发模式和敏捷开发模式。
1、瀑布开发模式瀑布开发模式是一种更倾向于严格控制的管理模式,要求在提出需求之后,充分完成项目的规划,各阶段都要经过严格的评审,只有当一个阶段的需求完成得非常好时才能进入下一个阶段。但是瀑布开发模式开发的失败率较高,且周期较长,于是就产生了敏捷开发模式。2、敏捷开发模式敏捷开发模式的核心是迭代开发,它将一个项目完整的开发流程分为了几个周期(也可以说是版本),由于每个版本的开发流程相似,看上去相当于一个重复迭代的过程。这么开发的好处是,使一个大的项目能在较短时间内上线,并在后续对它进行不断地迭代和优化。3、项目开发流程-立项-需求分析-原型图(产品画的)-切图-技术选型,数据库架构设计-前后端协同开发-上线测试服务器联调-测试-修改bug-上线运行
 
二、BBS多人博客项目基本功能和需求
 
比如:产品需求的确定,技术选型,数据库设计...
"""1. 用户表(你可以自己创建,也可以使用auth_user表)扩展auth_user表phone avatar:用来存储头像的地址create_time:用户注册的时间...blog_id = OneToOneField(to='blog')	2. 站点表(blog)站点名称站点标题站点样式:存的是css的路径3. 分类表(cate)分类名称blog = ForeignKey(to='blog')	4. 标签表标签名称blog = ForeignKey(to='blog')	5. 文章表(*******************article)文章标题文章摘要文章内容文章发表时间# 1. 通过文章id去点赞表或者评论表中查询# 优化# 2. 在文章表中增加子弹up_num			1down_num		1comment_num	    4# 外键关系子弹cate = ForeignKey(to='cate')	tag  = ManyToManyField(to='tag')blog = ForeignKey(to='blog')	6. 点赞点踩表谁给哪篇文章什么时间点了赞还是踩user		ForeignKey(to='user')	article		ForeignKey(to='article')	is_up			0/1create_timeid  	user_id  	article_id			is_up   create_time1			1			1					0		‘’2			2			1					1		‘’7. 	评论表(comment)谁给哪篇文章在什么时间评论了什么内容user		ForeignKey(to='user')	article		ForeignKey(to='article')	contentcreate_timeparent_id		ForeignKey(to='comment')	parent_id		ForeignKey(to='self')#自关联id  	user_id  	article_id			content   create_time parent_id1			1			1					0		‘’			02			2			1					1		‘’			13			2			1					1		‘’			2子评论!!!评论评论的评论!!!根评论1. Python是世界上最好的语言1.1 PHP是世界上最好的语言1.2 Java是世界上最好的语言无限极分类	category表id				cate_name			pid1				手机/数码			  02				电脑/办公			  0...20					手机通讯			121					运营商				 1...50				5G手机				2051				手机					20...100				128G/5G				50"""
 
三、项目程序设计
 

 
四、BBS数据库表结构设计
 
1.用户表:UserInfo
 
(通过继承AbstractUser类来扩写Auth_user)
•phone:用户的联系方式
•bg_img: 用户的主页背景
•province: 用户的省份
•city: 用户的城市
•gender : 用户的性别
•avatar:用户的头像
•blog:用户的博客站点(外键一对一关联博客表Blog)
 
2.博客表:Blog
 
•title:博客标题
•subtitle: 博客子标题
•style:博客样式
 
3.文章表:Article
 
•title:文章标题
•head_img: 头像
•description:文章摘要
•content:文章内容
•create_time:文章的创建时间
•modify_time:  文章的修改时间
•up_num :点赞数
•down_num:点踩数
•comment_num:评论数
•blog:属于哪个博客站点(外键关联博客表Blog)
•category:属于哪个分类(外键关联分类表Category)
 
4.标签表:Tag
 
•name:标签名
•blog:属于哪个博客站点(外键关联博客表Blog)
 
5.分类表:Category
 
•name:分类名
•blog:属于哪个博客站点(外键关联博客表Blog)
 
6.评论表:Comment
 
•user:评论的用户(外键关联用户表UserInfo)
•article:该评论属于哪篇文章(外键关联文章表Article)
•content:评论内容
•comment_time: 评论的创建时间
•comment_id:评论的目标id(外键进行自关联)
 
7.点赞点踩表:UpAndDown
 
•user:来自哪个用户(外键关联用户表UserInfo)
•article:属于哪篇文章(外键关联文章表Article)
•is_up:点赞还是点踩(根据bool值来判断)
•create_time : 点赞或踩的时间
 
8.文章标签表: Tag2Article
 
根据文章与标签的多对多关系手动建立的第三张表
•	tag:标签名(外键关联标签表Tag)
•	article:属于哪篇文章(外键关联文章表Article)
 
9.轮播图表 Swiper (拓展)
 
•	image: 轮播图图片名
•	title:轮播图标题
•	img_url: 点击轮播图要跳转的url地址
 
10.日志表: Log(拓展)
 
•	id: 日志id
•	ip: 访问的ip地址
•	time: 访问的时间
•	url: 访问的url
•	device: 访问的浏览器
•	platform:访问的操作系统类型
 
11.日志表: Log(拓展)
 
•	id: 日志id
•	ip: 访问的ip地址
•	time: 访问的时间
•	url: 访问的url
•	device: 访问的浏览器
•	platform:访问的操作系统类型
 
五、创建BBS表模型
 
模型层models.py中写入以下orm语句模型来创建表模型
 
from django.contrib.auth.models import AbstractUser
from django.utils.html import mark_safe
from django.db import models
from markdown import markdown
class Log(models.Model):id = models.AutoField(primary_key=True)ip = models.CharField(max_length=64, verbose_name='访问IP', help_text='访问用户的IP地址')time = models.DateTimeField(auto_now_add=True, verbose_name='访问时间', help_text='该用户的访问时刻')url = models.CharField(max_length=64, verbose_name='访问的URL', help_text='该用户访问的URL地址')device = models.CharField(max_length=256, null=True, verbose_name='访问的浏览器', help_text='该用户是用什么浏览器访问的')platform = models.CharField(max_length=256, null=True, verbose_name='访问的系统', help_text='该用户用的是什么操作系统')def __str__(self):return self.ipclass Meta:ordering = ['id']verbose_name_plural = '日志'
class UserInfo(AbstractUser):avatar = models.FileField(upload_to='avatar/', default='avatar/default.png', verbose_name='头像', help_text='该用户的头像')bg_img = models.FileField(upload_to='bg_img/', default='bg_img/default_bg.png', verbose_name='头像',help_text='该用户的主页背景')province = models.CharField(max_length=32, default='', verbose_name='省', help_text='该用户的省')city = models.CharField(max_length=32, default='', verbose_name='城市', help_text='该用户的市')gender = models.IntegerField(choices=((0, '保密'), (1, '男'), (2, '女')), default=0, verbose_name='性别',help_text='该用户的性别')phone = models.CharField(max_length=11, null=True, default='', verbose_name='联系方式', help_text='该用户的联系方式')blog = models.OneToOneField(to='Blog', on_delete=models.CASCADE, null=True, verbose_name='博客', help_text='该用户的博客')def __str__(self):return self.usernameclass Meta:verbose_name_plural = '用户'
class Blog(models.Model):title = models.CharField(max_length=32, verbose_name='博主昵称', help_text='博主昵称')subtitle = models.CharField(max_length=32, verbose_name='子标题/公告', help_text='博客的子标题/公告')style = models.CharField(max_length=32, verbose_name='样式', help_text='该博客独有的样式')  def __str__(self):return self.titleclass Meta:verbose_name_plural = '博客站点'
class Article(models.Model):title = models.CharField(max_length=32, verbose_name='标题', help_text='文章的标题')head_img = models.FileField(upload_to='article_head_img/', default='article_head_img/default_head.png',verbose_name='头图',help_text='文章的头图')description = models.CharField(max_length=128, verbose_name='摘要', help_text='简要描述该文章')content = models.TextField(verbose_name='内容', help_text='文章的内容')markdown = models.TextField(verbose_name='Markdown内容', default='暂无', help_text='文章的Markdown内容')create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='该文章的创建时间')modify_time = models.DateTimeField(auto_now=True, verbose_name='修改时间', help_text='该文章的最后修改时间')up_num = models.IntegerField(default=0, verbose_name='点赞数', help_text='该文章的点赞数')down_num = models.IntegerField(default=0, verbose_name='点踩数', help_text='该文章的点踩数')comment_num = models.IntegerField(default=0, verbose_name='评论数', help_text='该文章的评论数')blog = models.ForeignKey(to='Blog', on_delete=models.CASCADE, null=True, blank=True, verbose_name='博客',help_text='该文章属于哪个博客页面')category = models.ForeignKey(to='Category', on_delete=models.CASCADE, null=True, blank=True, verbose_name='分类',help_text='该文章属于哪个分类')tag = models.ManyToManyField(to='Tag', through='Tag2Article',through_fields=('article', 'tag'), verbose_name='标签',help_text='该文章有哪些标签')def get_text_md(self):return mark_safe(markdown(self.content))def __str__(self):return self.titleclass Meta:verbose_name_plural = '文章'ordering = ['id', ]
class Tag(models.Model):name = models.CharField(max_length=32, verbose_name='标签', help_text='标签的名字')blog = models.ForeignKey(to='Blog', on_delete=models.DO_NOTHING, null=True, blank=True, verbose_name='博客',help_text='该标签属于哪个博客页面')def __str__(self):return self.nameclass Meta:verbose_name_plural = '标签'
class Category(models.Model):name = models.CharField(max_length=32, verbose_name='分类', help_text='分类的名称')blog = models.ForeignKey(to='Blog', on_delete=models.DO_NOTHING, null=True, blank=True, verbose_name='博客',help_text='该分类属于哪个博客页面')def __str__(self):return self.nameclass Meta:verbose_name_plural = '分类'
class Comment(models.Model):user = models.ForeignKey(to='UserInfo', on_delete=models.DO_NOTHING, verbose_name='用户', help_text='该评论来自哪个用户')article = models.ForeignKey(to='Article', on_delete=models.CASCADE, null=True, verbose_name='文章',help_text='评论的对象是哪篇文章')content = models.CharField(max_length=256, verbose_name='内容', help_text='评论的内容')comment_time = models.DateTimeField(auto_now_add=True, verbose_name='时间', help_text='评论的时间')comment_id = models.ForeignKey(to='self', on_delete=models.CASCADE, null=True, verbose_name='评论id',help_text='对哪个id的评论进行评论')def __str__(self):return self.contentclass Meta:verbose_name_plural = '评论'
class UpAndDown(models.Model):user = models.ForeignKey(to='UserInfo', on_delete=models.CASCADE, verbose_name='用户', help_text='来自哪个用户')article = models.ForeignKey(to='Article', on_delete=models.CASCADE, null=True, verbose_name='文章',help_text='针对哪篇文章')is_up = models.BooleanField(null=True, verbose_name='点赞点踩', help_text='True为点赞,False为点踩')create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='点赞点踩的时间')def __str__(self):return self.userclass Meta:verbose_name_plural = '点赞点踩'
class Tag2Article(models.Model):tag = models.ForeignKey(to='Tag', on_delete=models.SET_DEFAULT, default='', verbose_name='标签', help_text='关联的标签')article = models.ForeignKey(to='Article', on_delete=models.CASCADE, default='', verbose_name='文章',help_text='关联的文章')class Meta:verbose_name_plural = '标签关联文章'
class Swiper(models.Model):image = models.FileField(upload_to='swiper_img/', default='swiper_img/default.jpg', verbose_name='图片',help_text='轮播图的图片')title = models.CharField(max_length=32, verbose_name='标题', help_text='图片的标题')img_url = models.CharField(max_length=64, verbose_name='URL', help_text='点击图片要跳转的URL地址')def __str__(self):return self.img_urlclass Meta:verbose_name_plural = '轮播图'
 
django2表设计
 
from django.db import models"""
先写普通字段
之后再写外键字段
"""
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):phone = models.BigIntegerField(verbose_name='手机号', null=True)avatar = models.FileField(upload_to='avatar/', default='avatar/default.png', verbose_name='用户头像')"""给avatar字段传文件对象 该文件会自动存储到avatar文件下 然后avatar字段只保存文件路径avatar/default.png"""create_time = models.DateField(auto_now_add=True)blog = models.OneToOneField(to='Blog', null=True, on_delete=models.CASCADE)
class Blog(models.Model):site_name = models.CharField(verbose_name='站点名称', max_length=32)site_title = models.CharField(verbose_name='站点标题', max_length=32)site_theme = models.CharField(verbose_name='站点样式', max_length=64)  
class Category(models.Model):name = models.CharField(verbose_name='文章分类', max_length=32)blog = models.ForeignKey(to='Blog', null=True, on_delete=models.CASCADE)
class Tag(models.Model):name = models.CharField(verbose_name='文章标签', max_length=32)blog = models.ForeignKey(to='Blog', null=True, on_delete=models.CASCADE)
class Article(models.Model):title = models.CharField(verbose_name='文章标题', max_length=64)desc = models.CharField(verbose_name='文章简介', max_length=255)content = models.TextField(verbose_name='文章内容')create_time = models.DateField(auto_now_add=True)up_num = models.IntegerField(verbose_name='点赞数', default=0)down_num = models.IntegerField(verbose_name='点踩数', default=0)comment_num = models.IntegerField(verbose_name='评论数', default=0)blog = models.ForeignKey(to='Blog', null=True, on_delete=models.CASCADE)category = models.ForeignKey(to='Category', null=True, on_delete=models.CASCADE)tags = models.ManyToManyField(to='Tag',through='Article2Tag',through_fields=('article', 'tag'))
class Article2Tag(models.Model):article = models.ForeignKey(to='Article', on_delete=models.CASCADE)tag = models.ForeignKey(to='Tag', on_delete=models.CASCADE)
class UpAndDown(models.Model):user = models.ForeignKey(to='UserInfo', on_delete=models.CASCADE)article = models.ForeignKey(to='Article', on_delete=models.CASCADE)is_up = models.BooleanField()  
class Comment(models.Model):user = models.ForeignKey(to='UserInfo', null=True, on_delete=models.CASCADE)article = models.ForeignKey(to='Article', null=True, on_delete=models.CASCADE)content = models.CharField(verbose_name='评论内容', max_length=255)comment_time = models.DateTimeField(verbose_name='评论时间', auto_now_add=True)parent = models.ForeignKey(to='self', null=True, on_delete=models.CASCADE)