zoukankan      html  css  js  c++  java
  • BBS功能分析

    1. 博客项目的需求分析(做什么功能)

    1. 登录功能(图片验证码)

    2. 注册功能(上传头像),基于forms

    3. 首页()

    4. 个人站点(个人样式不同,分类,标签,归档过滤)

    5. 文章内容

      1. kafka:消息队列

      2. rebbitmg(流量削峰)

    6. 点赞点彩

    7. 评论功能:公评论,子评论

    8. 后台管理

    9. 发布文章(富文本编辑器的使用,防止XSS攻击,XSS跨站脚本攻击,csrf跨站请求伪造)

    2. 设计程序(数据库设计)

    1. 用户表

    2. 一对多的关系一旦确定,关联字段要写在多的一方

    3. 博客表(和用户表是一对一) -分类表:一对多 -跟标签:一对多

    4. 文章表 -跟用户表:一对多

    5. 分类表(和文章表一对多)

    6. 标签表(和文章表是多对多,一个文章对多个标签,一个标签对应多个文章)

    7. 点赞、点踩表 -跟用户表: 一对多 -跟文章表:一对多

    8. 评论表 -跟用户表:一对多 -跟文章表:一对多:一个文章中多个评论对应的是一个表中的多个数据

    3. 数据迁移

    4. 登录功能

    知识点汇总:

    __str__ 就是print
    print就是调用里面的__str__方法


    唯一联合:一个用户只能给一片文章点赞
    unique_together = (('user','article'),)

    设立图片的四种方式:

    生成随机颜色
    def get_random_color():
       return (random.randint(0,255),random.randint(0,255),random.randint(0,255))

    方式一:返回固定图片
    with open('static/img/code.png','rb') as f:
       data = f.read()
    return Httpresponse(data)

    方式二:自动生图片,需要借助第三方模块pillow 图像处理的模块
    新生成一张图(保存在硬盘中)
    img = Image.new('RGB',(350,40),get_random_color())
    把图片保存起来
    with open('static/img/code.png','wb') as f:
       img.save(f)
    打开返回
    with open('/static/img/','rb') as f:
       data = f.read()
    return HttpResponse(data)

    方式三:不把文件保存在硬盘中,保存在内存中
    新生成一张图片
    img = Image.new('RGB',(350,40),get_random_color())
    生成Byteio对象
    f = BytesIO()
    把文件保存到对象中
    img.save(f,'png')
    把文件从对象中取出来
    f.getvalue()
    return HttpResponse(f.getvalue())

    方法四:在图片上写文件,并保存到内存中
    img = Image.new('RGB',(350,40),get_rnadom_color())
    写文字,生成一个字体对象
    font = ImageFont.truetype('/static/font/kumo.ttf',34)
    调用方法 返回一个画板对象
    draw = ImageDraw.Draw(img)
    draw.text((0,10),'python',font=font)

    f = BytesIO()
    img.save(f,'png')
    return HttpResponse(f.getvalue())

    动态生成大写小写数字5个

    for i in range(5):
       num = str(random.randint(0,9))
       up_chr=str(chr(random.randint(65,90)))
       lower_chr = str(chr(random.randint(97,122)))
    从三个字符任选
    ss = random.choice([num,up_chr,lower_chr])
    draw.text((20+i*50,5),ss,font=font,fill=get_random_color())

    画点和线


    画点和线
       width = 320
       height = 35
       for i in range(10):
           x1 = random.randint(0, width)
           x2 = random.randint(0, width)
           y1 = random.randint(0, height)
           y2 = random.randint(0, height)
           # 在图片上画线
           draw.line((x1, y1, x2, y2), fill=get_random_color())
           
       for i in range(100):
           # 画点
           draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())
           x = random.randint(0, width)
       #   y = random.randint(0, height)
       # 画弧形
       draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())

    建表:

    models.py

    from django.db import models
    from django.contrib.auth.models import AbstractUser


    class UserInfo(AbstractUser):
       nid = models.AutoField(primary_key=True)
       # 头像:FileField文件(varchar类型),default:默认值,upload_to上传的路径
       avatar = models.FileField(upload_to='avatar/', default='avatar/default.png')
       #跟blog表一对一
       #OneToOneField本质就是ForeignKey,只不过有个唯一性约束
       blog = models.OneToOneField(to='Blog', to_field='nid',null=True)
       # blog = models.ForeignKey(to='Blog', to_field='nid',null=True,unique=True)

       class Meta:
           # db_table='xxxx'
           # 在admin中显示的表名
           verbose_name='用户表'
           #去掉 用户表 后的s
           verbose_name_plural = verbose_name

    class Blog(models.Model):
       nid = models.AutoField(primary_key=True)
       #站点名称
       title = models.CharField(max_length=64)
       #站点副标题
       site_name = models.CharField(max_length=32)
       #不同人不同主题
       theme = models.CharField(max_length=64)
       def __str__(self):
           return self.site_name
    #分类表
    class Category(models.Model):
       nid = models.AutoField(primary_key=True)
       #分类名称
       title = models.CharField(max_length=64)
       #跟博客是一对多的关系,关联字段写在多的一方
       #to 是跟哪个表关联   to_field跟表中的哪个字段做关联, null=True 表示可以为空
       blog = models.ForeignKey(to='Blog', to_field='nid', null=True)
       def __str__(self):
           return self.title

    class Tag(models.Model):
       nid = models.AutoField(primary_key=True)
       #标签名字
       title = models.CharField(max_length=64)
       # 跟博客是一对多的关系,关联字段写在多的一方
       blog = models.ForeignKey(to='Blog', to_field='nid', null=True)
       def __str__(self):
           return self.title

    class Article(models.Model):
       nid = models.AutoField(primary_key=True)
       #verbose_name在admin中显示该字段的中文
       title = models.CharField(max_length=64,verbose_name='文章标题')
       #文章摘要
       desc = models.CharField(max_length=255)
       #文章内容 大文本
       content = models.TextField()
       #DateTimeField 年月日时分秒(注意跟datafield的区别)
       #auto_now_add=True:插入数据会存入当前时间
       #auto_now=True 修改数据会存入当前时间
       create_time = models.DateTimeField(auto_now_add=True)
       # commit_num=models.IntegerField(default=0)
       # up_num=models.IntegerField(default=0)
       # down_num=models.IntegerField(default=0)
    #一对多的关系
       blog = models.ForeignKey(to='Blog', to_field='nid', null=True)
       # 一对多的关系
       category = models.ForeignKey(to='Category', to_field='nid', null=True)
       #多对多关系 through_fields 不能写反了:
       tag = models.ManyToManyField(to='Tag', through='ArticleTOTag', through_fields=('article', 'tag'))
       def __str__(self):
           return self.title+'----'+self.blog.userinfo.username

    class ArticleTOTag(models.Model):
       nid = models.AutoField(primary_key=True)
       article = models.ForeignKey(to='Article', to_field='nid')
       tag = models.ForeignKey(to='Tag', to_field='nid')

    class Commit(models.Model):
       #谁对那篇文章评论了什么内容
       nid = models.AutoField(primary_key=True)
       user = models.ForeignKey(to='UserInfo', to_field='nid')
       article = models.ForeignKey(to='Article', to_field='nid')
       content = models.CharField(max_length=255)
       #评论时间
       create_time = models.DateTimeField(auto_now_add=True)
       #自关联()评论下面也可能会有子评论,所以要子关联
       parent = models.ForeignKey(to='self', to_field='nid',null=True,blank=True)

    class UpAndDown(models.Model):
       #谁对那篇文章点赞或点踩
       nid = models.AutoField(primary_key=True)
       user = models.ForeignKey(to='UserInfo', to_field='nid')
       article = models.ForeignKey(to='Article', to_field='nid')
       #布尔类型,本质也还是0和1
       is_up = models.BooleanField()

       class Meta:
           #联合唯一,一个用户只能给一片文章点赞或点踩
           unique_together = (('user', 'article'),)

    登录界面

    views.py


    from django.shortcuts import render,HttpResponse,redirect
    from django.http import JsonResponse
    #Image导入
    #ImageDraw在图片上写字
    #ImageFont 写字的格式
    from PIL import Image,ImageDraw,ImageFont
    import random
    # 相当于把文件以byte格式存到内存中
    from io import BytesIO
    # Create your views here.
    def login(request):
       if request.method=='GET':
           return render(request,'login.html')

    def get_random_color():
       return (random.randint(0,255),random.randint(0,255),random.randint(0,255))
    def get_code(request):
       #方式一,返回固定图片
       # with open('static/img/code.png','rb') as f:
       #     data=f.read()
       # return HttpResponse(data)
       #方式二,自动生成图片(需要借助第三方模块pillow)图像处理的模块
       #新生成一张图片
       # img=Image.new('RGB',(350,40),get_random_color())
       # #把图片保存起来
       # with open('static/img/code.png','wb') as f:
       #     #把图片保存起来(注意,用img对象的save方法,把f传入)
       #     img.save(f)
       # #打开返回
       # with open('static/img/code.png','rb') as f:
       #     data=f.read()
       # return HttpResponse(data)
       #方式三(不把文件保存在硬盘上,保存在内存中)
       #新生成一张图片
       # img=Image.new('RGB',(350,40),get_random_color())
       # #生成一个Byteio对象
       # f=BytesIO()
       # #把文件保存到对象中
       # img.save(f,'png')
       # #f.getvalue() 把文件从对象中取出来
       # return HttpResponse(f.getvalue())
       #方式四:在图片上写文件,并且保存到内存中
       # img = Image.new('RGB', (350, 40), get_random_color())
       # #写文字
       # #生成一个字体对象
       # font=ImageFont.truetype('static/font/kumo.ttf',34)
       # #调用方法,返回一个画板对象
       # draw=ImageDraw.Draw(img)
       # draw.text((0,10),'python',font=font)
       #
       # f=BytesIO()
       # img.save(f,'png')
       # return HttpResponse(f.getvalue())

       #最终版本
       img = Image.new('RGB', (350, 40), get_random_color())
       font=ImageFont.truetype('static/font/kumo.ttf',34)
       draw=ImageDraw.Draw(img)
       #动态生成大写,小写,数字 5个
       # draw.text((0,10),'python',font=font)
       for i in range(5):
           num=str(random.randint(0,9))
           up_chr=str(chr(random.randint(65,90)))
           lower_chr=str(chr(random.randint(97,122)))
           #从三个字符中选一个字符
           ss=random.choice([num,up_chr,lower_chr])
           draw.text((20+i*50, 5), ss, font=font,fill=get_random_color())
       #画点和线
       # width = 320
       # height = 35
       # for i in range(10):
       #     x1 = random.randint(0, width)
       #     x2 = random.randint(0, width)
       #     y1 = random.randint(0, height)
       #     y2 = random.randint(0, height)
       #     # 在图片上画线
       #     draw.line((x1, y1, x2, y2), fill=get_random_color())
       #
       # for i in range(100):
       #     # 画点
       #     draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())
       #     x = random.randint(0, width)
       #     y = random.randint(0, height)
       #     # 画弧形
       #     draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())
       f=BytesIO()
       img.save(f,'png')
       return HttpResponse(f.getvalue())
  • 相关阅读:
    解决 react-native 嵌套路由 warning
    在 function component 中设置 navigationOptions
    《客户端存储技术》阅读笔记
    表单实现原理(Vue ElementUI)
    MVVM 响应式原理(Vue)
    react 实现 loading 动效圈,支持配置转一圈的 duration
    CSS 数字设置等宽
    JSONP(Json with padding)
    javascript this对象
    css盒子模型
  • 原文地址:https://www.cnblogs.com/zrx19960128/p/11444908.html
Copyright © 2011-2022 走看看