BBS01- 个人博客项目搭建、BBS多人博客项目基本功能和需求、项目程序设计、BBS数据库表结构设计

项目配置文件setting.py

INSTALLED_APPS = [
    'bbs',
]


TEMPLATES = [
    {
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
    },
]

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'bbs2',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'USER': 'root',
        'PASSWORD': 'root',
        'CHARSET': 'utf8'
    },
}



LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = False

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

# 全局登录配置
# LOGIN_URL = '/login/'

# auth_user表扩展
# AUTH_USER_MODEL = 'bbs.UserInfo'
AUTH_USER_MODEL = 'bbs.UserInfo'

# media文件夹的开放
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

一、BBS-个人博客项目完整搭建

项目开发流程
一、项目分类
现在互联网公司需要开发的主流web项目一般分为两类:面向互联网用户,和公司内部管理。

面向互联网用户: C(consumer)端项目
公司内部管理:B(business)端项目

还有一类web应用,基本采用基于角色的权限控制,不同的员工在这套系统中拥有不同的权限,
适用于公司内部管理。

基于权限的后台关系系统:
	RBAC权限管理系统

二、项目开发模式分类
最常见的两类为瀑布开发模式和敏捷开发模式。
1、瀑布开发模式
	瀑布开发模式是一种更倾向于严格控制的管理模式,要求在提出需求之后,充分完成项目的规划,各阶段都要经过严格的评审,只有当一个阶段的需求完成得非常好时才能进入下一个阶段。
	但是瀑布开发模式开发的失败率较高,且周期较长,于是就产生了敏捷开发模式。
	
2、敏捷开发模式
	敏捷开发模式的核心是迭代开发,它将一个项目完整的开发流程分为了几个周期(也可以说是版本),由于每个版本的开发流程相似,看上去相当于一个重复迭代的过程。这么开发的好处是,使一个大的项目能在较短时间内上线,并在后续对它进行不断地迭代和优化。
	
3、项目开发流程
	-立项
	-需求分析
	-原型图(产品画的)
	-切图
	-技术选型,数据库架构设计
	-前后端协同开发
	-上线测试服务器联调
	-测试
	-修改bug
	-上线运行

二、BBS多人博客项目基本功能和需求

# 开发任意的项目第一个阶段就是弄清楚你要开发什么功能

# 一个项目最重要的是表结构的设计,大部分时间都是用来设计表.
# 你在企业中对于一个完成的项目写代码的时间大概有个30%,其余的时间都用来做铺垫
比如:产品需求的确定,技术选型,数据库设计...

# 注册登录功能
"""
	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			1
		down_num		1
		comment_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/1
		create_time
		
		id  	user_id  	article_id			is_up   create_time
		1			1			1					0		‘’
		2			2			1					1		‘’
	7. 	评论表(comment)
		
		谁给哪篇文章在什么时间评论了什么内容
		user		ForeignKey(to='user')	
		article		ForeignKey(to='article')	
		content
		create_time
		parent_id		ForeignKey(to='comment')	
		parent_id		ForeignKey(to='self')
		#自关联
		
		id  	user_id  	article_id			content   create_time parent_id
		1			1			1					0		‘’			0
		2			2			1					1		‘’			1
		3			2			1					1		‘’			2
		
		
		子评论!!!
		评论评论的评论!!!
		根评论
		
		1. Python是世界上最好的语言
			1.1 PHP是世界上最好的语言
				1.2 Java是世界上最好的语言
				
			
	 无限极分类	
		category表
		id				cate_name			pid
		1				手机/数码			  0
		2				电脑/办公			  0
		
		...
		20					手机通讯			1
		21					运营商				 1
		...
		
		
		
		50				5G手机				20
		51				手机					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:访问的操作系统类型

五、models.py

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.ip
    # 定义这个表在admin后台中显示的别名
    class 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.username

    class 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.title

    class 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.title

    class 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.name

    class 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.name

    class 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.content

    class 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.user

    class 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_url

    class Meta:
        verbose_name_plural = '轮播图'

models.py

from django.db import models

"""
先写普通字段
之后再写外键字段
"""
from django.contrib.auth.models import AbstractUser


# auth_user的扩展表(用户表)
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)  # 存css/js的文件路径


# 分类表
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)
    # 文章内容有很多 一般情况下都是使用TextField
    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()  # 传布尔值 存0/1


# 评论表
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)  # 有些评论就是根评论

在这里插入图片描述

如果遇到上述错误:
	我是改了源码解决的。
	
注意:
	若你扩展了auth_user表,一定要在配置文件(settings.py)中声明
	在配置文件settings中声明使用自定义的User类:
	# 指定使用自定义的模型类:
	AUTH_USER_MODEL = 'bbs.UserInfo'

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值