• (1) 设计表结构


    设计表结构(使用mysql):

    BBS-Demp/settings.py

     1 LANGUAGE_CODE = 'zh-hans'    # admin显示中文
     3 TIME_ZONE = 'Asia/Shanghai'    # 时区,默认UTC
     5 USE_I18N = True
     7 USE_L10N = True
     9 USE_TZ = False                        # 时区,默认True
    10 
    12 DATABASES = {
    13     'default': {
    14         'ENGINE': 'django.db.backends.mysql',
    15         'NAME': 'cnblog',        # 数据库名
    16         'USER': 'root',          # 用户名
    17         'PASSWORD': 'root',      #密码
    18         'HOST': '127.0.0.1',     #主机ip
    19         'PORT': 3306             # 端口
    20     }
    21 }            
    22 AUTH_USER_MODEL = 'app01.UserInfo'

    BBS_Demo/__init__.py导入pymysql

    1 import pymysql
    2 
    3 pymysql.install_as_MySQLdb()

    app01/models.py

      1 from django.db import models
      2 from django.contrib.auth.models import AbstractUser
      3 
      4 # Create your models here.
      5 class UserInfo(AbstractUser):
      6     """
      7     用户信息
      8     """
      9     telephone = models.CharField(max_length=11, null=True, unique=True, verbose_name='手机号')
     10     avatar = models.FileField(upload_to='avatars/', default='/avatars/default.png', verbose_name='头像')
     11     create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
     12 
     13     blog = models.OneToOneField(to='Blog', null=True,on_delete=models.CASCADE)
     14 
     15     def __str__(self):
     16         return self.username
     17 
     18 
     19 class Blog(models.Model):
     20     """
     21     博客信息表
     22     """
     23     title = models.CharField(max_length=64, verbose_name='个人博客标题')
     24     site_name = models.CharField(max_length=64, verbose_name='站点名称')
     25     theme = models.CharField(max_length=32, verbose_name='博客主题',null=True,blank=True)
     26 
     27     def __str__(self):
     28         return self.title
     29 
     30 
     31 class Category(models.Model):
     32     """
     33     博主个人文章分类表
     34     """
     35     title = models.CharField(max_length=32, verbose_name="分类标题")
     36     blog = models.ForeignKey(to='Blog', verbose_name='所属博客',on_delete=models.CASCADE)
     37 
     38     def __str__(self):
     39         return self.title
     40 
     41 
     42 class Tag(models.Model):
     43     """
     44     博主个人文章标签表
     45     """
     46     title = models.CharField(max_length=32, verbose_name='标签名称')
     47     blog = models.ForeignKey(to='Blog', verbose_name='所属博客',on_delete=models.CASCADE)
     48 
     49     def __str__(self):
     50         return self.title
     51 
     52 
     53 class Article(models.Model):
     54     """
     55     博主个人文章表
     56     """
     57     title = models.CharField(max_length=64, verbose_name='文章标题')
     58     desc = models.CharField(max_length=256, verbose_name='文章摘要')
     59     create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
     60     content = models.TextField(verbose_name='文章内容')
     61 
     62     comment_count = models.IntegerField(default=0,verbose_name='文章评论数')
     63     up_count = models.IntegerField(default=0,verbose_name='推荐数')
     64     down_count = models.IntegerField(default=0,verbose_name='反对数')
     65 
     66     user = models.ForeignKey(to='UserInfo', verbose_name='作者',on_delete=models.CASCADE)
     67     category = models.ForeignKey(to='Category', null=True, verbose_name='文章分类',on_delete=models.SET_NULL)
     68     # 自己手动创建第三张表
     69     tags = models.ManyToManyField(to='Tag', through='Article2Tag', through_fields=('article', 'tag'),
     70                                   verbose_name='文章标签')
     71 
     72     def __str__(self):
     73         return self.title
     74 
     75 
     76 class Article2Tag(models.Model):
     77     article = models.ForeignKey(to='Article', verbose_name='文章',on_delete=models.CASCADE)
     78     tag = models.ForeignKey(to='Tag', verbose_name='标签',on_delete=models.CASCADE)
     79 
     80     class Meta:
     81         # 联合唯一
     82         unique_together = [('article', 'tag'), ]
     83 
     84     def __str__(self):
     85         return self.article.title + '---' + self.tag.title
     86 
     87 
     88 class ArticleUpDown(models.Model):
     89     """
     90     点赞表
     91     """
     92     user = models.ForeignKey('UserInfo', null=True,on_delete=models.CASCADE)
     93     article = models.ForeignKey('Article', null=True,on_delete=models.CASCADE)
     94     is_up = models.BooleanField(default=True)
     95 
     96     class Meta:
     97         unique_together = [
     98             ('article', 'user'),
     99         ]
    100 
    101 
    102 class Comment(models.Model):
    103     """
    104     评论表:对文章的评论、对评论的评论
    105     """
    106     article = models.ForeignKey('Article', verbose_name='评论文章',on_delete=models.CASCADE)
    107     user = models.ForeignKey('UserInfo', verbose_name='评论者',on_delete=models.CASCADE)
    108     create_time = models.DateTimeField(auto_now_add=True, verbose_name='评论时间')
    109     content = models.CharField(max_length=256, verbose_name='评论内容')
    110     # 父评论 自关联
    111     parent_comment = models.ForeignKey(to='self', null=True,on_delete=models.CASCADE)
    112 
    113     def __str__(self):
    114         return self.content

    表结构流程图

    说明:

    • USE_TZ = False  表示使用无时区的时间。TIME_ZONE = 'Asia/Shanghai'  表示使用本地时区。当True是,表示不管time_zone怎么设置,都不生效,所以我们一般设置为Flase。
    • LANGUAGE_CODE = 'zh-hans'  表示设置为中国区域,使用中文。

    • 用户信息表继承的是Django内置的AbstractUser类,而不是User类。from  django. contrib.auth.models  import  AbstractUser,这样继承有什么好处?虽然User本质也是继承AbstractUser,但是为了我们扩展更多的自定义字段,就继承AbstractUser。但是别忘了settings.py加  AUTH_USER_MODEL = 'app01.UserInfo'  表示使用app01下的UserInfo模型类,生成的表也是app01_userinfo为名。
    • 一个分类对应多篇文章,而分类删除的时候,文章不能删除,所以设置了
      1 class  Article(models.Model):
          pass
      2 category = models.ForeignKey(to='Category', null=True,verbose_name='文章分类',on_delete=models.SET_NULL) 3 # 文章也可以没有分类,所以可以为null。
    • 一个标签对应多个文章,一个文章对应多个分类。是多对多关系,但是这里没有使用Django自动创建第三张表,而是写了个 Article2Tag 类,用来记录article_id 和tag_id的关系。
    • 对于点赞、反对、评论三个功能。在Article类中增加三个字段记录数目就行了。增加点赞表、反对表、评论表,与用户直接建立关系,表示那个用户对哪个文章进行了什么操作。
    • 这里这里最难得属评论表了,评论分两种,一个是对文章的评论,一个是对评论的评论。

      其实这里是利用了自关联,

      1 # 父评论 自关联
      2     parent_comment = models.ForeignKey(to='self', null=True,on_delete=models.CASCADE)

      上面的表格的评论关系就一目了然了。

    • UserInfo模型类中还有一个头像字段,用来保存用户头像的。这里要细说一下。

       当用户上传头像的时候,能拿到一个文件对象file_obj。但是我们怎么保存到我们服务器呢?

      avatar = models.FileField(upload_to='avatars/', default='/avatars/default.png', verbose_name='头像')  这里必须接收一个文件对象,但数据库保存的只是一个文件相对路径字符串,所以这肯定要配置,Django会帮我们把文件对象保存到我们upload=path的path路径,如果没有这个文件夹,将自动生成,前面我们都知道setting.py文件配置过

    1 # 别名,用于url访问
    2 STATIC_URL = '/static/'
    3 
    4 # 静态文件存放路径
    5 STATICFILES_DIRS = [
    6     os.path.join(BASE_DIR, 'static')
    7 ]

     Django对静态文件的区分有两种

    1. /static/         js、css、image、fonts等
    2. /media/       用户上传的文件

    media和static配置类似:

    1 # 绝对路径  用来保存用户上传的文件
    2 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
    3 # 让用户url可以访问  但要配置urls.py
    4 MEDIA_URL = '/media/'
    5 #
    会将文件下载到media文件夹中 以后文件都会保存到media文件夹下,耦合性非常棒,做到了统一
    
    

    但这还不够,static虽然在根目录,但是用户可以访问,那些是无关紧要的,看了就看了,其他文件不能看,因为static是django已经帮我们配好路由,我们的media并没有,用户访问不了,所以还要在urls.py

    1 from django.views.static import serve
    2 from . import settings
    3 from django.urls import path, re_path
    4 
    5 urlpatterns = [
    6     # media配置
    7     re_path(r'media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT}),
    8 ]

     别问为什么,就是这样做,通过上面两部,用户上传的头像或文件会自动保存到/media/avatars/文件夹下,用户url也可以访问。

     

  • 相关阅读:
    从狄利克雷卷积到莫比乌斯函数
    Codeforces Round #613 (Div. 2)
    Codeforces Round #612 (Div. 2)
    CTF:第五题
    CTF:第四题
    CTF:第三题
    CTF,第二题
    CTF,第一题
    我也要做CTF了,哎,人老了,脑子需要动一动了,第一节,配置本地环境
    websocket JS使用方式
  • 原文地址:https://www.cnblogs.com/xjmlove/p/9935406.html
Copyright © 2020-2023  润新知