BBS项目(二)
BBS项目(二)

可以在本地写或虚拟环境
- 添加虚拟环境

- 如果虚拟环境启动报错:解决 query = query.decode(errors=‘replace‘) AttributeError: ‘str‘ object has no attribute ‘decode‘
- 解决办法
query = query.decode(errors='replace')
'''换成'''
query = errors='replace'
ORM 创建相关表
'''models.py'''
from django.contrib.auth.models import AbstractUser
from django.db import models
# Create your models here.
'''扩写auth_user表需要使用AbstractUser'''
# 用户表
class UserInfo(AbstractUser):
    phone = models.CharField(max_length=32, null=True, verbose_name='手机号')
    # 头像
    avatar = models.FileField(upload_to='avatar/', default='avatar/default.png', verbose_name='头像')
    blog = models.OneToOneField(to='Blog', on_delete=models.CASCADE, null=True, verbose_name='博客表外键')
# 博客表
class Blog(models.Model):
    # 博客标题
    site_title = models.CharField(max_length=32)
    # 博客名称
    site_name = models.CharField(max_length=32)
    # 博客样式
    # 每个人的样式不同,添加文件地址
    site_style = models.CharField(max_length=32)
    def __str__(self):
        return self.site_title  # print对象打印
    class Meta:
        # admin进入以后看到的名字
        verbose_name_plural = '博客表'
# 标签表
class Tag(models.Model):
    name = models.CharField(max_length=32)
    blog = models.ForeignKey(to='Blog', on_delete=models.CASCADE)
    def __str__(self):
        return self.name
    class Meta:
        verbose_name_plural = '标签表'
# 分类表
class Category(models.Model):
    name = models.CharField(max_length=32)
    blog = models.ForeignKey(to='Blog', on_delete=models.CASCADE)
    def __str__(self):
        return self.name
# 文章表
class Article(models.Model):
    title = models.CharField(max_length=32, verbose_name='文章标题')
    # help_text:提示信息,只针对于admin
    desc = models.CharField(max_length=128, verbose_name='文章摘要', help_text='这里写入文章摘要~')
    # 文本内容
    content = models.TextField()
    # 创建时间
    create_time = models.DateTimeField(auto_now_add=True)
    # 优化字段,减少数据库查询操作,评论数,点赞数
    # up_num = models.IntegerField(default=0)
    # down_num = models.IntegerField(default=0)
    # commit_num = models.IntegerField(default=0)
    # 关联关系
    blog = models.ForeignKey(to='Blog', on_delete=models.CASCADE)
    category = models.ForeignKey(to='Category', on_delete=models.CASCADE)
    # 多对多关系,through:第三张表,through_fields:关联字段
    '''注意through_fields填写关联字段,当前在哪个表,第一个就是哪个字段'''
    tag = models.ManyToManyField(to='Tag', through='TagToArticle', through_fields=('article', 'tag'))
    def __str__(self):
        try:
            return self.title + '-------' + self.blog.site_title  # 显示作者
        except:
            return self.title
    class Meta:
        verbose_name_plural = '文章管理'
# 多对多中间表
class TagToArticle(models.Model):
    tag = models.ForeignKey(to='Tag', on_delete=models.CASCADE)
    article = models.ForeignKey(to='Article', 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)
    # 实质存的时候,是0和1
    is_up = models.BooleanField()
    create_time = models.DateTimeField(auto_now_add=True)
# 评论表
class Commit(models.Model):
    user = models.ForeignKey(to='UserInfo', on_delete=models.CASCADE)
    article = models.ForeignKey(to='Article', on_delete=models.CASCADE)
    content = models.CharField(max_length=256)
    create_time = models.DateTimeField(auto_now_add=True)
    # 存父评论的id号
    # commit_id=models.IntegerField()
    # commit=models.ForeignKey(to='Commit')
    # 自关联
    commit_id = models.ForeignKey(to='Commit', on_delete=models.CASCADE, null=True)
'''sesstings.py'''
# 数据库配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'bbs',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'USER': 'root',
        'PASSWORD': '7410',
        'CHARSET': 'utf8'
    }
}
AUTH_USER_MODEL = "blog.UserInfo"  # 继承了AbstractUser需要配置
'''__init__.py'''
import pymysql
pymysql.install_as_MySQLdb()
'''表迁移'''
makemigrations
migrate
# 如果不迁移就报错
ValueError: Dependency on app with no migrations: account

表模型

修改admin样式
'''创建超级用户'''
manage.py@BBS > createsuperuser
Username:  HammerZe
Password:  7410
'''修改配置'''
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False

参考:Simple UI
Simple-UI
- 导入: - pip install django-simpleui
- 注册: 
  INSTALLED_APPS = [
      'simpleui',
      'django.contrib.admin',
      'django.contrib.auth',
      'django.contrib.contenttypes',
      'django.contrib.sessions',
      'django.contrib.messages',
      'django.contrib.staticfiles',
      ...
  ]


样式改变
注册表添加数据
'''admin.py'''
from django.contrib import admin
from blog import models
# Register your models here.
admin.site.register(models.Article)
admin.site.register(models.Blog)
admin.site.register(models.UserInfo)
admin.site.register(models.UpAndDown)
admin.site.register(models.Commit)
admin.site.register(models.Category)
admin.site.register(models.Tag)

应用名改成中文在后台显示
'''apps.py'''
from django.apps import AppConfig
class App01Config(AppConfig):
    name = 'blog'
    verbose_name = '博客管理'
# 如果想改表名为中文在后台显示,只需在类中添加Meta类
    class Meta:
        # admin进入以后看到的名字
        verbose_name_plural = '博客表'

注册forms类编写
'''forms校验'''
from django import forms
from django.forms import widgets
'''注册校验,写入样式'''
class RegisterForm(forms.Form):
    # 名称校验
    username = forms.CharField(
        max_length=18, min_length=3,label='用户名',
        error_messages={'required': '该字段必填', 'max_length': '名字过长,不能超过18个字符',
                        'min_length': '名字过短,不能少于三个字符'},
        widget=widgets.TextInput(attrs={'class': 'form-control'})
    )
    # 密码校验
    password = forms.CharField(
        max_length=18, min_length=3,label='密码',
        error_messages={'required': '该字段必填', 'max_length': '密码过长,不能超过18个字符',
                        'min_length': '密码过短,不能少于三个字符'},
        widget=widgets.PasswordInput(attrs={'class': 'form-control'})
    )
    re_password = forms.CharField(
        max_length=18, min_length=3,label='确认密码',
        error_messages={'required': '该字段必填', 'max_length': '密码过长,不能超过18个字符',
                        'min_length': '密码过短,不能少于三个字符'},
        widget=widgets.PasswordInput(attrs={'class': 'form-control'})
    )
    # 邮箱
    email = forms.EmailField(
        error_messages={'required': '该字段必填', 'invalid': '邮箱格式不正确'},label='邮箱',
        widget=widgets.EmailInput(attrs={'class': 'form-control'})
    )
注册功能前端搭建
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Register</title>
    <script src="/static/element/jQuery3.4.js"></script>
    <script src="/static/element/bootstrap.min.js"></script>
    <link rel="stylesheet" href="/static/element/bootstrap.min.css">
</head>
<body>
<div class="container">
    <div class="row" style="margin-top: 15px">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-primary">
                <div class="panel-heading">
                    <h3 class="panel-title">注册 </h3>
                </div>
                <div class="panel-body">
                    <form action="" id='my_form' method="post">
                        {% for item in form %}
                            <div class="form-group">
                                {#  后端blog_forms.py获取label #}
                                {#    item.auto_id获取当前id自动聚焦    #}
                                <label for="{{ item.auto_id }}">{{ item.label }}</label>
                                {{ item }}
                                <span></span>
                            </div>
                        {% endfor %}
                        {#   头像   #}
                        <div class="form-group">
                            {#  后端blog_forms.py获取label #}
                            <label for="myfile">上传头像
                                <img src="/static/img/default_img.jpg" id="id_img" width="80px" height="80px"
                                     style="margin:10px 10px">
                            </label>
                            <input type="file" id="myfile" style="display: none">
                            {# 实现点击头像就能上传文件,img放入label标签内,隐藏掉input框 #}
                        </div>
                        {#   提交,使用form表单,类型要写成button,如果是submit的话会触发表单提交  #}
                        <div class="text-center">
                            <input type="button" class="btn btn-primary" value="注册">
                            <input type="button" class="btn btn-warning" value="退出">
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
{# 实现上传头像,显示图片 #}
<script>
    $('#myfile').change(function () {
        {#获取上传头像文件#}
        var myfile = $(this)[0].files[0]
        {# 借助文件阅读器把文件读到这个对象中,attr添加属性,显示图片#}
        var filereader = new FileReader()
        filereader.readAsDataURL(myfile)
        {#等待读取完成,放入img标签上#}
        filereader.onload = function () {
            {#  读取成功执行  #}
            $('#id_img').attr('src', filereader.result)
        }
    })
</script>
</html>
头像实时显示功能实现
<script>
    $('#myfile').change(function () {
        //取到文件
        let myfile=$(this)[0].files[0]
        //let myfile=$('#myfile')
        //借助文件阅读器对象,把文件读到这个对象中
        let filereader=new FileReader()
        filereader.readAsDataURL(myfile)
        //等待读完,把它放到img标签上
        filereader.onload=function () {
            $('#id_img').attr('src',filereader.result)
        }
        //$('#id_img').attr('src','https://upload-images.jianshu.io/upload_images/9522239-c31b38a1a9913ac4.png?imageMogr2/auto-orient/strip|imageView2/2/w/202/format/webp')
    })
</script>

BBS项目(二)的更多相关文章
- BBS项目分布搭建二(个人站点相关)
		BBS项目分布搭建二 1. 首页详情补充 # 在home.html文件中 body标签内补充: <div class="container-fluid"> <di ... 
- python 自动化之路 day 20 Django进阶/BBS项目【一】
		一.django进阶 1.django orm 增删改查 1.1.创建表: 1 2 3 >>> from blog.models import Blog >>> b ... 
- BBS项目知识点汇总
		目录 bbs项目知识点汇总 一. JavaScript 1 替换头像 2 form表单拿数据 3 form组件error信息渲染 4 添加html代码 5 聚焦操作 二 . html在线编辑器 三 . ... 
- 小福bbs—项目系统设计与数据库设计
		这个作业属于哪个课程 班级链接 这个作业要求在哪里 作业要求的链接 团队名称 小福bbs 这个作业的目标 实现对校园论坛软件的制作,使其能够发布帖子,查看信息等 作业的正文 小福bbs--项目需求分析 ... 
- 小福bbs——项目需求分析
		# 一.简单了解 这个作业属于哪个课程 班级链接 这个作业要求在哪里 作业要求的链接 团队名称 小福bbs 这个作业的目标 第一个版本,根据项目预期情况形成 作业的正文 小福bbs--项目需求分析 其 ... 
- day75 bbs项目☞后台管理+修改头像
		目录 一.后台管理之添加文章 二.修改用户头像 bbs项目总结 一.后台管理之添加文章 添加文章有两个需要注意的问题: 文章的简介切取,应该想办法获取到当前文章的文本内容后再截取字符 XSS攻击,由于 ... 
- BBS项目分布搭建五(评论相关功能实现)
		BBS项目分布搭建五(评论相关) 1. 根评论逻辑实现 # 在models.py文件中 修改: # 7. 评论表 parent = models.ForeignKey(to='self', null= ... 
- Eclipse+Maven创建webapp项目<二> (转)
		Eclipse+Maven创建webapp项目<二> 1.开启eclipse,右键new——>other,如下图找到maven project 2.选择maven project,显 ... 
- Vue小项目二手书商城:(四)详情页和购物车(emit、prop、computed)
		实现效果: 点击对应商品,对应的商品详情页出现,详情页里面还有“Add to cart”按钮和“×”退出按钮. 点击“Add to cart”可以将商品加入购物车,每件商品只能添加一次,如果把购物车的 ... 
随机推荐
- Idea中新建package包,却变成了Directory
			问题描述 今天在IdeaJava工程src下新建了一个名字叫包implements的包,右键在里面新建类时,却发现根本就没有Class这个选项,然后发现implements这个包的图标也和其他包的图标 ... 
- Token+Redis实现接口幂等性
			一.什么是 幂等性 在编程中,幂等性的特点就是其任意多次执行的效果和一次执行的效果所产生的影响是一样的. 二.Token+Redis的实现思路 1.数据提交前要向服务的申请 token(用户登录时可以 ... 
- Java线程--Phaser使用
			原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11867895.html Java线程--Phaser使用, 代码里头有详细注释: packag ... 
- Linux防火墙(iptables/firewalld)
			Linux防火墙(iptables/firewalld) 目录 Linux防火墙(iptables/firewalld) 一.iptables 1. iptables概述 2. netfilter和i ... 
- Linux小技巧scp命令
			Linux服务器运维小技巧scp命令详细教程. 前言 今天给大家带来的是linux中比较实用的命令scp.善用小技巧,解决工作中的痛点. 掌握一门好的技术或者说一门好的艺术,最快捷的方式就是融入到工作 ... 
- 手写一个线程池,带你学习ThreadPoolExecutor线程池实现原理
			摘要:从手写线程池开始,逐步的分析这些代码在Java的线程池中是如何实现的. 本文分享自华为云社区<手写线程池,对照学习ThreadPoolExecutor线程池实现原理!>,作者:小傅哥 ... 
- Git重命名远程分支
			一.重命名本地分支 将hot_fix分支重命名为bug_fix git branch -m hot_fix bug_fix 二.推送重命名后的本地分支到远程仓库 git push origin bug ... 
- Redis 源码简洁剖析 11 - 主 IO 线程及 Redis 6.0 多 IO 线程
			Redis 到底是不是单线程的程序? 多 IO 线程的初始化 IO 线程运行函数 IOThreadMain 如何推迟客户端「读」操作? 如何推迟客户端「写」操作? 如何把待「读」客户端分配给 IO 线 ... 
- 如何在 Xamarin 中快速集成 Android 版认证服务 - 邮箱地址篇
			Xamarin 作为微软提供的移动服务多系统开发平台,成为很多开发者首选的应用开发平台.AppGallery Connect(以下简称 AGC)也在逐步的支持 Xamarin 的 SDK.认证服务也是 ... 
- 03并发编程(多道技术+进程理论+进程join方法)
			目录 03 并发编程 03 并发编程 
