blog开发之表结构设计
表结构设计
直接先看代码:
from django.db import models # Create your models here. from django.contrib.auth.models import AbstractUser __all__ = ['UserInfo', 'Blog', 'Category', 'Tag', 'Article', 'Article2Tag', 'ArticleUpDown', 'Comment'] class UserInfo(AbstractUser): nid = models.AutoField(primary_key=True) telephone = models.CharField(verbose_name='电话号码', null=True, unique=True, max_length=32) avatar = models.FileField(verbose_name='头像', upload_to='avatars/',default='avatars/default.png') create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True) blog = models.OneToOneField('Blog', verbose_name='博客', on_delete=models.CASCADE, null=True) def __str__(self): return self.username class Blog(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='博客标题', max_length=32) def __str__(self): return self.title class Category(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='分类名称', max_length=32) blog = models.ForeignKey('Blog',verbose_name='博客',on_delete=models.CASCADE) def __str__(self): return self.title class Tag(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='标签名称', max_length=32) blog = models.ForeignKey('Blog', verbose_name='博客', on_delete=models.CASCADE) def __str__(self): return self.title class Article(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='文章标题', max_length=32) desc = models.CharField(verbose_name='文章摘要', max_length=255) content = models.TextField(verbose_name='文章内容') create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True) comment_count = models.IntegerField(default=0) up_count = models.IntegerField(default=0) down_count = models.IntegerField(default=0) user = models.ForeignKey('UserInfo', verbose_name='作者', on_delete=models.CASCADE) category = models.ForeignKey('Category', verbose_name='所属分类', on_delete=models.CASCADE, null=True) tag = models.ManyToManyField( to='Tag', through='Article2Tag', through_fields=('article', 'tag') ) def __str__(self): return self.title class Article2Tag(models.Model): nid = models.AutoField(primary_key=True) article = models.ForeignKey('Article', on_delete=models.CASCADE) tag = models.ForeignKey('Tag', on_delete=models.CASCADE) class Meta: unique_together = [ ('article', 'tag') ] def __str__(self): return f'{self.article.title}--{self.tag.title}' class ArticleUpDown(models.Model): nid = models.AutoField(primary_key=True) user = models.ForeignKey('UserInfo', on_delete=models.CASCADE) article = models.ForeignKey('Article', on_delete=models.CASCADE) is_up = models.BooleanField(default=True) class Meta: unique_together = [ ('user', 'article') ] class Comment(models.Model): nid = models.AutoField(primary_key=True) user = models.ForeignKey('UserInfo', on_delete=models.CASCADE) article = models.ForeignKey('Article', on_delete=models.CASCADE) content = models.TextField(verbose_name='评论内容') create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True) parent_comment = models.ForeignKey('self', on_delete=models.CASCADE,null=True)
需要注意的点:
1.UserInfo表继承Django的AbstracUser。UserInfo表里就不需要有auth_user里重复的字段了,比如说username以及password等,但是还是可以直接使用这些字段的,并且django会自动将password进行加密。所以你定义的UserInfo表的字段可以起一个扩展的作用。
#第一步:导入AbstractUser from django.contrib.auth.models import AbstractUser # 第二步:继承 class UserInfo(AbstractUser): .... # 第三步:settings中配置: "app名.UserInfo" AUTH_USER_MODEL = 'blog.UserInfo'
# 创建普通用户:
UserInfo.objects.create_user(username='用户名', password='密码')
# 创建系统用户:
UserInfo.objects.create_superuser(username='用户名', password='密码')
再次注意:
一旦我们指定了新的认证系统所使用的表,我们就需要重新在数据库中创建该表,而不能继续直接使用原来默认的auth_user表了。
2. 关于FileField字段
avatar = models.FileField(verbose_name='头像', upload_to='avatars/',default='avatars/default.png')
这个upload_to:'avatars/',代表想让用户上传的文件,图片都放到这个目录里。
需要在settings中配置:
MEDIA_URL = "/media/" MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
如果还想让用户可以访问服务器上的文件,图片。就需要配置url中media了:
from django.views.static import serve from django.conf import settings app_name = 'blog' urlpatterns = [ ..... re_path(r"^media/(?P<path>.*)$",serve,{"document_root":settings.MEDIA_ROOT}), ..... ]
然后页面就可以通过该URL获取相关资源了,比如获取自己的头像:
<a href="{% url 'blog:home_site' article.user.username %}">
<img src="/blog/media/{{ article.user.avatar }}" width="56" height="56" alt="">
</a>
注意一点:
是否需要暴露服务器上的哪些文,需要谨慎!
3. Article表设计:
comment_count = models.IntegerField(default=0) up_count = models.IntegerField(default=0) down_count = models.IntegerField(default=0)
# 这三个字段,本来可以通过数据库查询获取,写成IntegerField是为了减少数据库的读取。你评论的时候,后台就执行评论数据的写入
,并把文章表的comment_count字段加1就可以了,另外两个是一样的。