サンプルブログの構築
ブログを構築するためのRedisを使用する方法を示し
ブログの例
主な機能
ユーザーアカウントは、記事の公開
ホームページで見る記事を
分類に応じた記事を表示するのには、
レビュー
ユーザーアカウント
ユーザーアカウント
ブログのアカウントにサインアップすることが必要です。
- 口座番号(アカウント)は、英語や数字で構成することができ、ブログが一意のIDとして使用され、複製することはできません。
- パスワード。
- 名前は、ニックネーム(ニックネーム)、記事やレビューを公開したときに表示しました。
アカウントの一意性を保証することは、以前に紹介しUniqueSetクラスを使用して実装することができ、店舗の利用者情報は、ハッシュを格納するために使用することができます。
ストアのユーザー情報
ユーザーごとに、プログラムは、ユーザーに関する店舗情報へブログ::ハッシュキーのユーザーのためのフォーマット::フォーマットを作成し、ユーザ名に基づいています。
たとえば、「zhang19870511」のアカウントに、パスワードは「12345」で、「サン」のユーザー愛称、プログラムは、ユーザに関する情報を格納するには、次のコマンドを実行します:
::ブログ:: zhang19870511ユーザーHMSETは、アカウントzhang19870511の
パスワード12345
ニックネームジョー・スミスは、
ユーザー抽象クラスへのユーザーアカウント関連の操作になります。
ユーザー类API
Userクラスは、例を使用しています
>>> user = User(client)
>>> user.create(‘zhang19870511’, ‘12345’, ‘张三’)
>>> user.get_by_account(‘zhang19870511’)
{'account': 'zhang19870511', 'password': '12345', 'nickname': '张三'}
>>> user.try_login(‘‘zhang19870511’, ‘12345’)
{'account': 'zhang19870511', 'password': '12345', 'nickname': '张三'}
記事を公開
例の記事
記事を公開の原則
タイトル、コンテンツ、カテゴリ、著者、時間やその他の情報の放出組成物によって、各記事には、各記事のために、プログラムは、ブログ::記事のストレージ・フォーマットに関連した固有のID、情報や記事を生成するIdGeneratorクラスを使用します::ハッシュキーの内部。
示例:
HMSET blog::post::9125 id 9125
title “前后端分离的思考与实践(六)”
content “关于前后端分享的思考, ……”
category “前端技术”
author_account “jianfei”
time 1410239558
我们可以将针对文章的相关操作抽象为 Post 类。
Post 类 API
>>> post = Post(client)
>>> id = post.create(“前后端分离的思考与实践(六)”,
“关于前后端分享的思考,……”,
“前端技术”,
“jianfei”)
>>> post.get_by_id(id)
在主页查看文章
主页显示的文章
主页文章的实现原理
主页会按照文章的发布日期,按从新到旧的 顺序来排列博客包含的文章。
为了储存这些文章,程序会使用一个名 为 blog::index 的列表来储存博客文章,每当有新文章 发布的时候,程序就会将新文章的 ID 推入到这个列表里面。
举个例子,当用户新创建了 ID 为 9125 的文章时,程序将执行以下命令,将文章推入到首 页的文章列表中:
LPUSH blog::index 9125
当用户访问主页的时候,程序会使用 LRANGE 取出列表中最近发布的一些文章,并将它 们展示给用户观看。
我们可以将针对主页文章列表的操作抽象为 Index 类。
Index 类 APi
>>> index = Index(client)
>>> index.push(‘10086’)
>>> index.push(‘10087’)
>>> index.paging(1, 10)
[‘10087’, ‘10086’, …]
根据分类查看文章
分类文章示例
文章分类的实现原理
对于博客的每个分类,程序使用一个格式为 blog::category:: 的列表来储存属于 name 分类的所有文章。
每当有新的文章发布时,程序就会使用 LPUSH 命令,将新文章的 ID 推入到相应的分类文章列表里面,这样我们就会得到一个按照发布时间从新到旧来排列的文章列表。
:新しい記事9125リリースの「フロントエンド技術」カテゴリに属するとき、例えば、プログラムは記事が内部の記事のリストに「フロントエンド技術」対応に押し込まれ、次のコマンドを実行します
LPUSHカテゴリ::ブログ:: 9125フロントエンド技術
私たちは、分類のための操作Categoryクラスのブログに抽象的なことができます。
CategoryクラスのAPI
カテゴリー例
>>> front_end = Category(client, ‘前端技术’)
>>> front_end.include_post(‘12345’)
>>> front_end.include_post(‘128256’)
>>> front_end.include_post(‘251474’)
>>> front_end.count_post()
3
>>> front_end.paging(1, 10)
[‘251474’, ‘128256’, ‘12345’]
レビュー
コメントは記事の例をブログ
コメントを実現
各コメントには、時間と内容を公開、コメント作成者が含まれており、それぞれの記事のために、記事の下のコメントのすべてを格納するためのリストが存在しなければなりません。、この要求に先立ちとまったく同じマイクロブログとコメントフォーラムのための当社のシステムを構築する限りCommentクラスとCommentListクラスに若干の変更が以前に定義されたとして、あなたがプログラム内でこのブログでそれらを再利用することができます。
レビュー
関数とその実装の原則
id_generator.py
# coding: utf-8
class IdGenerator:
"""
使用字符串键实现的自增唯一 ID 生成器。
"""
def __init__(self, client, key):
"""
设置储存 ID 生成器当前值的键。
"""
self.client = client
self.key = key
def init(self, n):
"""
初始化生成器的值,需要在系统正式运行之前调用,用于保留少于等于 n 的 ID 号码。
"""
# 如果键 key 已经有值,那么说明 gen() 已经执行过
# 为了防止产生重复的 ID ,程序不能执行这个 init() 操作
if self.client.get(self.key) is not None:
raise Exception
self.client.set(self.key, n)
def gen(self):
"""
生成一个新的唯一 ID 。
"""
new_id = self.client.incr(self.key)
return int(new_id)
unique_set.py
# encoding: utf-8
class UniqueSet:
def __init__(self, client, key):
self.client = client
self.key = key
def add(self, element):
self.client.sadd(self.key, element)
def is_include(self, element):
return self.client.sismember(self.key, element)
user.py
# encoding: utf-8
def make_user_key(account):
return 'blog::user::' + account
class User:
"""
用户账号操作。
"""
def __init__(self, client):
self.client = client
def create(self, account, password, nickname):
"""
创建新用户,创建钱需要确保给定的 account 未被占用。
"""
key = make_user_key(account)
info = {
'account': account,
'nickname': nickname,
'password': password
}
self.client.hmset(key, info)
def get_by_account(self, account):
key = make_user_key(account)
return self.client.hgetall(key)
def try_login(self, account, password):
user_info = self.get_by_account(account)
if (user_info is not None) and (user_info['password'] == password):
return user_info
post.py
# encoding: utf-8
from time import time as current_time
from id_generator import IdGenerator
ID_GENERATOR_KEY = 'blog::post_ids'
def make_post_key(post_id):
return 'blog::post::' + str(post_id)
class Post:
"""
文章相关操作。
"""
def __init__(self, client):
self.client = client
def create(self, title, content, category, author_account):
"""
创建一篇新文章。
"""
post_id = IdGenerator(client, ID_GENERATOR_KEY).gen()
post_hash = make_post_key(post_id)
info = {
'id': post_id,
'time': current_time(),
'title': title,
'content': content,
'category': category,
'author_account': author_account
}
self.client.hmset(post_hash, info)
return post_id
def get_by_id(self, post_id):
post_hash = make_post_key(post_id)
return self.client.hgetall(post_hash)
index.py
def __init__(self, client):
self.client = client
self.post_list = make_index_key()
def push(self, post_id):
"""
将文章推入到列表里面。
"""
self.client.lpush(self.post_list, post_id)
def count_post(self):
"""
返回列表目前已有的文章数量。
"""
return self.client.llen(self.post_list)
def paging(self, n, count):
"""
对文章进行分页。
"""
start_index = (n-1)*count
end_index = n*count-1
return self.client.lrange(self.post_list, start_index, end_index)
category.py
# encoding: utf-8
def make_category_key(name):
return 'blog::category::' + name
class Category:
"""
创建一个分类列表来储存所有属于某个分类的文章。
"""
def __init__(self, client, name):
self.client = client
self.post_list = make_category_key(name)
def include_post(self, post_id):
"""
将指定的文章添加到当前分类里面。
"""
self.client.lpush(self.post_list, post_id)
def count_post(self):
return self.client.llen(self.post_list)
def paging(self, n, count):
"""
按时间从新到旧的顺序,以 count 篇文章为一页,返回当前分类第 n 页上的文章。
"""
start_index = (n-1)*count
end_index = n*count-1
return self.client.lrange(self.post_list, start_index, end_index)
comment.py
# encoding: utf-8
from time import time
from id_generator import IdGenerator
ID_GENERATOR_KEY = 'blog::comment_ids'
def make_comment_key(comment_id):
return 'blog::comment::' + str(comment_id)
class Comment:
"""
帖子评论相关操作。
"""
def __init__(self, client):
self.client = client
def create(self, author_id, content):
"""
创建一个新的评论。
"""
comment_id = IdGenerator(client, ID_GENERATOR_KEY).gen()
comment_hash = make_comment_key(comment_id)
info = {
'id': comment_id,
'author_id': author_id,
'content': content,
'time': time()
}
self.client.hmset(comment_hash, info)
return comment_id
def get_by_id(self, comment_id):
"""
根据评论 id ,查找并返回评论的详细信息。
"""
comment_hash = make_comment_key(comment_id)
return self.client.hgetall(comment_hash)
comment_list.py
# encoding: utf-8
def make_comment_list_key(post_id):
return 'blog::post::' + str(post_id) + '::comments'
class CommentList:
"""
创建一个列表来记录某一帖子下的所有评论(的 ID)。
"""
def __init__(self, client, post_id):
"""
设置被评论的帖子的 ID 。
"""
self.client = client
self.post_id = post_id
self.comment_list = make_comment_list_key(post_id)
def push(self, comment_id):
"""
将评论推入到评论列表里面。
"""
self.client.lpush(self.comment_list, comment_id)
def count(self):
"""
返回帖子目前已有的评论数量。
"""
return self.client.llen(self.comment_list)
def paging(self, number, count):
"""
以分页形式返回帖子的评论。
"""
start_index = (number-1)*count
end_index = number*count-1
return self.client.lrange(self.comment_list, start_index, end_index)