Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Django 文章数据模型设计及演进 #3

Open
codetalks-new opened this issue Feb 18, 2019 · 4 comments
Open

Django 文章数据模型设计及演进 #3

codetalks-new opened this issue Feb 18, 2019 · 4 comments
Labels
主题模块 主题相关设计演进文档

Comments

@codetalks-new
Copy link
Owner

目前的基本设计如下:

class Post(BaseModel,SoftDeleteMixin):
  # 显示指定主键 设计成 uuid 是为了避免被直接遍历爬取
  id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
  node = models.ForeignKey(Node, verbose_name="节点", on_delete=models.PROTECT)
  creator = models.ForeignKey(WepostUser, verbose_name="创建者", on_delete=models.PROTECT)
  title = models.CharField("标题", max_length=128)
  content = models.TextField("内容",max_length=40960)
  content_rendered = models.TextField("渲染内容",max_length=81920, default='')
  # 运营相关
  order = models.IntegerField("排序",default=0)
  # 回复相关冗余
  last_reply_by = models.CharField("最后回复人",max_length=150, blank=True, default='')
  last_touched = models.DateTimeField(auto_now=True, verbose_name='最后活跃')
  reply_count = models.PositiveIntegerField("回复数", default=0)
  # 统计相关数据
  like_count = models.PositiveIntegerField("喜欢数", default=0)
  dislike_count = models.PositiveIntegerField("不喜欢数", default=0)
  fav_count = models.PositiveIntegerField("收藏数", default=0)
  share_count = models.PositiveIntegerField("分享数", default=0)
  member_view_count = models.PositiveIntegerField("会员浏览数", default=0)
  other_view_count = models.PositiveIntegerField("网页浏览数", default=0)

值得说明的是

  1. BaseModel 继承了 created,updated 字段。
  2. SoftDeleteMixin 继承了 _deleted_at 字段,此字段用于记录对应文章是否被软删除了。
  3. 文章内容目录主要支持 markdown格式, content 主要用来保存原始的编辑内容,而 content_rendered 缓存 渲染成的 html 格式文档。
@codetalks-new codetalks-new added the 主题模块 主题相关设计演进文档 label Feb 18, 2019
@codetalks-new
Copy link
Owner Author

codetalks-new commented Feb 18, 2019

回复打算支持盖楼,因此基于 MPTT 来设计的,也就是支持树形结构

class Reply(MPTTModel, BaseModel, SoftDeleteMixin, BaseReactStatMixin):
  ref = TreeForeignKey('self', null=True, blank=True, related_name="replies", on_delete=models.SET_NULL,
                       verbose_name="引用")
  creator = models.ForeignKey(WepostUser, verbose_name="回复人", on_delete=models.PROTECT)
  content = models.TextField("内容", max_length=4096)
  content_rendered = models.TextField("渲染内容", max_length=8192, default='')
  #
  creator_name = models.CharField("回复人名", max_length=150)  # 冗余数据
  reply_from = models.CharField("回复人来源", max_length=64, help_text="用户来源地点等信息")
  reply_ip = models.GenericIPAddressField("回复IP")

点赞收藏分享等统计数据,提取出作为 BaseReactStatMixin, Post 的数据模型中的对应字段也改为从 BaseReactStatMixin 中继承

class BaseReactStatMixin(models.Model):
  # 基本反馈统计相关数据
  like_count = models.PositiveIntegerField("喜欢数", default=0)
  dislike_count = models.PositiveIntegerField("不喜欢数", default=0)
  fav_count = models.PositiveIntegerField("收藏数", default=0)
  share_count = models.PositiveIntegerField("分享数", default=0)

  class Meta:
    abstract = True

@codetalks-new
Copy link
Owner Author

给文章添加状态字段,习惯上是使用一个枚举来创建状态变量。
于是先创建一个简单的状态枚举,可以满足基本的要求了。

class PostState(IntEnum):
  # 基本状态
  DRAFT = 1
  PUBLISHED = 6

  @property
  def label(self):
    return _post_state_to_text[self]


_post_state_to_text = {
  PostState.DRAFT: "草稿",
  PostState.PUBLISHED: "已发布",
}

Post 模型增加的 state 字段声明如下:

  state = models.SmallIntegerField("状态", choices=PostState.choices(), default=PostState.DRAFT)

@codetalks-new
Copy link
Owner Author

上面的 Reply 模型忽略了 对 Post 的引用。
但是如果 Reply 要增加对 Post 的引用这分为两种方案。
1) 添加 Comment 模型,Comment 中增加对 Post 的引用,而 Reply 添加对 Comment 的引用。

2)直接在 Reply 中添加对 Post 的引用,然后使用 reply.parent is null 来判断是否是直接针对 Post 的评论。

在 添加一个 Comment 数据模型会增加一个中间表,后面从 Reply 得到 Post 信息会麻烦一些。而且也增加了维护多一个数据模型的工作,所以选择的方案是直接在 Reply 中增加对 Post 的引用。

 post = models.ForeignKey(Post, on_delete=models.CASCADE, verbose_name="主题")

@codetalks-new
Copy link
Owner Author

Reply 模型添加 增加 order 字段,方便后续运营

  order = models.IntegerField("排序", default=0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
主题模块 主题相关设计演进文档
Projects
None yet
Development

No branches or pull requests

1 participant