报障系统项目整理
1、数据库设计:
from django.db import models class UserInfo(models.Model): """ 用户表 """ nid = models.BigAutoField(primary_key=True) username = models.CharField(verbose_name='用户名', max_length=32, unique=True) 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', related_name='f', through_fields=('user', 'follower')) class Blog(models.Model): """ 博客信息 """ nid = models.BigAutoField(primary_key=True) title = models.CharField(verbose_name='个人博客标题', max_length=64) 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='nid') class UserFans(models.Model): """ 互粉关系表 """ user = models.ForeignKey(verbose_name='博主', to='UserInfo', to_field='nid', related_name='users') follower = models.ForeignKey(verbose_name='粉丝', to='UserInfo', to_field='nid', related_name='followers') class Meta: unique_together = [ ('user', 'follower'), ] class Category(models.Model): """ 博主个人文章分类表 """ nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='分类标题', max_length=32) blog = models.ForeignKey(verbose_name='所属博客', to='Blog', to_field='nid') class ArticleDetail(models.Model): """ 文章详细表 """ content = models.TextField(verbose_name='文章内容', ) article = models.OneToOneField(verbose_name='所属文章', to='Article', to_field='nid') class UpDown(models.Model): """ 文章顶或踩 """ article = models.ForeignKey(verbose_name='文章', to='Article', to_field='nid') user = models.ForeignKey(verbose_name='赞或踩用户', to='UserInfo', to_field='nid') 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', related_name='back', null=True) article = models.ForeignKey(verbose_name='评论文章', to='Article', to_field='nid') user = models.ForeignKey(verbose_name='评论者', to='UserInfo', to_field='nid') class Tag(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='标签名称', max_length=32) blog = models.ForeignKey(verbose_name='所属博客', to='Blog', to_field='nid') class Article(models.Model): nid = 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) comment_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='nid') category = models.ForeignKey(verbose_name='文章类型', to='Category', to_field='nid', null=True) type_choices = [ (1, "Python"), (2, "Linux"), (3, "OpenStack"), (4, "GoLang"), ] # 网站分类 article_type_id = models.IntegerField(choices=type_choices, default=None) tags = models.ManyToManyField( to="Tag", through='Article2Tag', through_fields=('article', 'tag'), ) class Article2Tag(models.Model): article = models.ForeignKey(verbose_name='文章', to="Article", to_field='nid') tag = models.ForeignKey(verbose_name='标签', to="Tag", to_field='nid') class Meta: unique_together = [ ('article', 'tag'), ]
用户信息表(ID、账号、密码、主题id) 用户 ------> 文章 一对多 主题表(ID、主题)用户表外建 文章表(ID、文章标题、文章内容、发表时间、文章阅读量、用户id(外建用户id)) 文章 ------> 评论 多对多 评论表(ID、文章id(外建文章表)、评论内容、评论时间、评论者id(外建用户表)、回复id(null=true,内联评论id)) 点赞表(ID、文章id(外建文章id)、赞、踩、用户id(外建用户id)) (文章id&赞&用户id)&(文章id&踩&用户id)联合唯一 互粉表(ID、关注id、粉丝id) 内联用户表 文章标签(ID、标签名、文章id) 多对多
创建数据库:blog_db
2、django配置:
1、数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'blog_db',
'USER': 'root',
'PASSWORD': '123.com',
'HOST': 'localhost',
'PORT': '3306',
}
}
#导入模块
import pymysql
pymysql.install_as_MySQLdb()
2、静态文件
STATICFILES_DIRS = (
os.path.join(BASE_DIR,'static'),
)
构建数据库表:
python manage.py makemigrations python manage.py migrate
2、功能开发
- 主页:
主页代码【待补充】#urls.py url(r'^all/(?P<type_id>\d+)/', views.index), url(r'^', views.index), #views.py def index(request,*args,**kwargs): #获取当前页 # print(request.path_info) condition = {} type_id = int(kwargs.get('type_id')) if kwargs.get('type_id') else None if type_id: condition['article_type_id'] = type_id type_choice_list=models.Article.type_choices article_list = models.Article.objects.all() return render( request, 'index.html', { 'type_choice_list':type_choice_list, 'article_list':article_list, 'type_id':type_id, } ) #index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css"> <link rel="stylesheet" href="/static/css/commons.css"> </head> <body> <nav class="navbar navbar-default no-radius"> <div class="container"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">一个很牛逼的技术论坛</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> {% if type_id %} <li><a href="/">全部</a></li> {% else %} <li class="active"><a href="/">全部</a></li> {% endif %} {% for item in type_choice_list %} {% if item.0 == type_id %} <li class="active"><a href="/all/{{ item.0 }}/">{{ item.1 }}</a></li> {% else %} <li><a href="/all/{{ item.0 }}/">{{ item.1 }}</a></li> {% endif %} {% endfor %} </ul> <ul class="nav navbar-nav navbar-right"> <li><a href="/login/">登录</a></li> <li><a href="#">注册</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <div> <div class="container"> <div class="col-md-8"> <div class="article-list"> <div class="article-item"> <h3 class="art-head"><a href="">运维自动化</a></h3> <div class="art-body clearfix"> <a class="left" href=""><img src="/static/images/devops.png" alt=""></a> 本文根据 DevOpsDays 北京站演讲记录整理而成,重点是关于阿里巴巴DevOps 转型之后,运维平台如何建设的。 </div> <div class="art-footer"> <a href=""> <span class="glyphicon glyphicon-user">高路川</span> </a> </div> </div> {% for article in article_list %} <div class="article-item"> <h3 class="art-head"><a href="">{{ article.title }}</a></h3> <div class="art-body clearfix"> <a class="left" href=""><img src="{{ article.blog.user.avatar }}" alt=""></a> {{ article.summary }} </div> <div class="art-footer"> <a href=""> <span class="glyphicon glyphicon-user">高路川</span> </a> </div> </div> {% endfor %} </div> </div> <div class="col-md-4"> <div class="panel panel-default"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> <p>2222</p> <p>2222</p> <p>2222</p> </div> </div> <div class="panel panel-default"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> <p>11111</p> <p>11111</p> <p>11111</p> </div> </div> </div> </div> </div> </body> </html>
- 登录:
登录代码【待补充】#urls.py url(r'^login/', views.login), #views.py def login(request): return render(request,'login.html') #login.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css"> <style> .login{ width: 550px; margin: 0 auto; border: 1px solid #dddddd; padding: 20px; margin-top: 80px; } </style> </head> <body> <div class="login"> <h3>用户登录</h3> <form class="form-horizontal"> <div class="form-group"> <label class="col-sm-2 control-label">用户名:</label> <div class="col-sm-8"> <input type="text" class="form-control" id="inputEmail3" placeholder="用户名" name="username"> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">密码:</label> <div class="col-sm-8"> <input type="password" class="form-control" placeholder="密码" name="password"> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">验证码:</label> <div class="col-sm-4"> <input type="text" class="form-control" placeholder="密码" name="code"> </div> <div class="col-sm-4"> <img style="width: 120px;height: 30px" src="/check_code/" alt=""> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <div class="checkbox"> <label> <input type="checkbox"> Remember me </label> </div> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <input type="submit" class="btn btn-default" value="登录"> </div> </div> </form> </div> </body> </html>
- 验证码:
验证码代码#urls.py url(r'^check_code/', views.check_code), #views.py def check_code(request): # 读取硬盘中的文件,在页面显示 # f = open('static/images/devops.jpg','rb') # data = f.read() # f.close() # return HttpResponse(data) #这种方式不需要写入磁盘,并读取 # pip3 install pillow # from PIL import Image # f = open('code.png','wb') #拿到一个文件句柄 # img = Image.new(mode='RGB',size=(120,30),color=(255,255,255)) #长120,宽30,三个255,就是白色 # img.save(f,'png') #设置后缀为png格式 # f.close() # f = open('code.png','rb') # data = f.read() # f.close() # return HttpResponse(data) """ # 以下这种方式可以拿来既用,适合生产环境 f = BytesIO() img = Image.new(mode='RGB',size=(120,30),color=(255,255,255)) draw = ImageDraw.Draw(img, mode='RGB') draw.point([10,10],fill="red") draw.point([20, 10], fill=(255, 255, 255)) #画点 draw.line((15, 10, 50, 30), fill='red') draw.line((45, 20, 100, 100), fill=(197, 255, 255)) #画线 draw.arc((0, 0, 30, 30), 0, 360, fill="red") #画圆 # draw.text([0, 0], 'python', "red") # font = ImageFont.truetype("kumo.ttf",28) # draw.text([0,0],'python',(0,255,0),font=font) #画字 import random # char_list = [] # for i in range(5): # char = chr(random.randint(65,90)) # char_list.append(char) # ''.join(char_list) # v = ''.join([chr(random.randint(65,90)) for i in range(5)]) #列表生成式 for i in range(5): char = chr(random.randint(65,90)) font = ImageFont.truetype("kumo.ttf",28) draw.text([i*24,0],char,(random.randint(0,255),random.randint(0,255),random.randint(0,255)),font=font) img.save(f,'png') data = f.getvalue() code = ''.join(char_list) request.session['code'] = code """ from PIL import Image, ImageDraw, ImageFont from io import BytesIO from utils.random_check_code import rd_check_code img,code = rd_check_code() stream = BytesIO() img.save(stream,'png') request.session['code'] = code return HttpResponse(stream.getvalue()) #login.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css"> <style> .login{ width: 550px; margin: 0 auto; border: 1px solid #dddddd; padding: 20px; margin-top: 80px; } </style> </head> <body> <div class="login"> <h3>用户登录</h3> <form class="form-horizontal"> <div class="form-group"> <label class="col-sm-2 control-label">用户名:</label> <div class="col-sm-8"> <input type="text" class="form-control" id="inputEmail3" placeholder="用户名" name="username"> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">密码:</label> <div class="col-sm-8"> <input type="password" class="form-control" placeholder="密码" name="password"> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">验证码:</label> <div class="col-sm-4"> <input type="text" class="form-control" placeholder="密码" name="code"> </div> <div class="col-sm-4"> <img style="width: 120px;height: 30px" src="/check_code/" alt=""> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <div class="checkbox"> <label> <input type="checkbox"> Remember me </label> </div> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <input type="submit" class="btn btn-default" value="登录"> </div> </div> </form> </div> </body> </html>

浙公网安备 33010602011771号