数据库设计主要考虑如下几点:
1、博客系统中哪些数据需要存储到数据库中,比如用户、文章、评论、文章的分类、标签等
2、考虑实体存在哪些属性,比如用户需要有:用户名、密码、邮箱、头像、电话等。文章需要有标题、简述、内容、点击次数等
3、考虑实体的各个属性的约束,比如用户的邮箱不能重复;文章必须有标题等
4、考虑这些实体间的关系,比如文章和标签之间是多对多的;文章和用户是多对一的;
5、从web需求或数据统计的需要再次审查实体和属性是否合理。
设计实体或数据库的表可以采用专门的工具,比如powerdesigner,erwin等。本次我使用Navicat Data Modeler,主要是他比较小巧,但是又足够用。
给出示意图如下:
从图中很容易看到各个实体间的关系,多对多需要有一个中间表blog_article_tag
既然有了关系图,将其转换成python的model也很容易。
from django.db import models from django.contrib.auth.models import AbstractUser # 用户 class User(AbstractUser, models.Model): avatar = models.ImageField(upload_to='avatar/%Y/%m', default='avatar/default.png', max_length=200, blank=True, null=True, verbose_name='用户头像') qq = models.CharField(max_length=20, blank=True, null=True, verbose_name='QQ号码') mobile = models.CharField(max_length=11, blank=True, null=True, unique=True, verbose_name='手机号码') class Meta: verbose_name = "用户" verbose_name_plural = verbose_name ordering = ['id'] def __str__(self): return self.username # 标签 class Tag(models.Model): name = models.CharField(max_length=50, verbose_name="标签") def __str__(self): return self.name class Meta: verbose_name = "标签" verbose_name_plural = verbose_name ordering = ['id'] # 文章分类 class Category(models.Model): name = models.CharField(max_length=30, verbose_name="分类名称") index = models.IntegerField(verbose_name='显示顺序(从小到大)', default=999) def __str__(self): return self.name class Meta: verbose_name = "文章分类" verbose_name_plural = verbose_name ordering = ['index', '-id'] # 文章 class Article(models.Model): title = models.CharField(max_length=50, verbose_name="文章标题") description = models.CharField(max_length=200, verbose_name="描述") content = models.TextField(verbose_name="内容") click_count = models.IntegerField(verbose_name="点击次数", default=0) is_recommend = models.BooleanField(verbose_name="是否推荐", default=False) date_publish = models.DateTimeField(auto_now_add=True, verbose_name='发布时间') user = models.ForeignKey(User, verbose_name='用户') category = models.ForeignKey(Category, blank=True, null=True, verbose_name='分类') tag = models.ManyToManyField(Tag, verbose_name='标签') class Meta: verbose_name = "文章" verbose_name_plural = verbose_name ordering = ['-date_publish'] def __str__(self): return self.title # 评论模型 class Comment(models.Model): content = models.TextField(verbose_name='评论内容') date_publish = models.DateTimeField(auto_now_add=True, verbose_name='发布时间') user = models.ForeignKey(User, blank=True, null=True, verbose_name='用户') article = models.ForeignKey(Article, blank=True, null=True, verbose_name='文章') pid = models.ForeignKey('self', blank=True, null=True, verbose_name='父级评论') class Meta: verbose_name = '评论' verbose_name_plural = verbose_name ordering = ['-date_publish'] def __str__(self): return str(self.id) # 友情链接 class Links(models.Model): title = models.CharField(max_length=50, verbose_name='标题') description = models.CharField(max_length=200, verbose_name='友情链接描述') callback_url = models.URLField(verbose_name='url地址') date_publish = models.DateTimeField(auto_now_add=True, verbose_name='发布时间') index = models.IntegerField(default=999, verbose_name='排列顺序(从小到大)') class Meta: verbose_name = '友情链接' verbose_name_plural = verbose_name ordering = ['index', 'id'] def __str__(self): return self.title # 广告 class Ad(models.Model): title = models.CharField(max_length=50, verbose_name='广告标题') description = models.CharField(max_length=200, verbose_name='广告描述') image_url = models.ImageField(upload_to='ad/%Y/%m', verbose_name='图片路径') callback_url = models.URLField(null=True, blank=True, verbose_name='回调url') date_publish = models.DateTimeField(auto_now_add=True, verbose_name='发布时间') index = models.IntegerField(default=999, verbose_name='排列顺序(从小到大)') class Meta: verbose_name = u'广告' verbose_name_plural = verbose_name ordering = ['index', 'id'] def __str__(self): return self.title
由于我们使用了django自带的AbstractUser,我们需要再配置文件中增加
# 自定义用户model
AUTH_USER_MODEL = 'blog.User'
最后我们需要把models中的实体同步到数据库的表中。django为我们提供了非常好的工具。
manage.py@Blog_Django > makemigrations
manage.py@Blog_Django > migrate
至此,博客系统中的表已经设计完毕,下一步我们要使用Django自带的admin来管理这些表。