使用Python的Bottle和Bootstrap来制作类似Instagram的网站(续集)
请注意
在试错中进行开发的同时,我也在撰写文章,因此已不再是可以让他人阅读的文本。它完全是个人备忘录。
1. 上次的概要和这次的目标
为了开发像Instagram这样的Web应用程序,首先我们制作了一个模型。
目前为止,我们只能加载带有顺序编号的图片和文本,还不能派上用场。
因此,我们将在第二阶段引入mongoDB来使用数据库。
2. 完成目标图
我打算在数据库中创建一个“用户信息”集合和一个“发布内容”集合。它们的内容分别如下:
“用户信息集合”= {userdbID,userID}
“发布内容集合”= {entryID,userdbID,imgfilename,comment}
通过userdbID来管理用户,并从“发布内容集合”中提取带有userdbID的数据来显示。
3. 准备好 mongoDB
在bottle中已经存在一个名为bottle-mongo的插件。我已经安装了它。
我在mLab中注册了一个提供MongoDB数据服务的帐户,并免费使用了500MB的空间。
我在mLab上创建了一个名为”chenstagram”的数据库,并对该数据库进行用户注册(此注册与mLab的用户注册不同)。注册时所使用的用户名和专用于数据库的密码需要安全地保存,以便在进行数据库的读写操作时使用。
现在我们打算在这个数据库中创建一个名为”userinfo”的集合,并将userID保存在里面。
4. 调用数据库
在项目内创建一个database.py文件,并导入MongoPlugin。
在这里写下刚才注册数据库用户时的用户名和密码,并按照以下步骤创建db_plugin。
只要知道用户名和密码,就可以访问数据库,这样写在明处感觉有安全问题,但我不知道如何处理,所以这次只将文件分开。关于安全措施,我打算稍后向专业人士征求意见。
from bottle.ext.mongo import MongoPlugin
def createDatabase():
username = "??????"
password = "??????"
database_name = "chenstagram"
database_uri = "mongodb://" + username + ":" + password + "@ds117878.mlab.com:17878/" + database_name
db_plugin = MongoPlugin(uri =database_uri , db = database_name)
return db_plugin
在Bottle上安装数据库!
回到chenstagram.py(不再触碰database.py),将数据库安装到bottle中。
import database
db_plugin = database.createDatabase()
app.install(db_plugin)
通过这个操作,一个神奇的魔法生效了,只需要调用名为mongodb的变量,就能够访问数据库!
6. 用户注册功能的实施
首先,以简单的形式实现用户注册功能。
当访问”/register/”时,我们会注册。
但是,如果已经存在该,则不会执行任何操作。
我们只需要注册用户名。
注册完成后让它跳转到用户页面吧。
我认为这些部分以后会有大幅升级,所以随便写写吧。
@app.route("/register/<userID>")
def database(mongodb , userID) :
#データベースを検索してすでに存在しないかを検証
query = mongodb["userinfo"].find({"userID" : userID})
if query.count() == 0 :
#登録する
userdbID = mongodb["userinfo"].insert_one( {"userID" : userID } ).inserted_id
return redirect("/" + userID)
else :
#すでに存在している
return redirect("/" + userID)
尝试将用户信息注册到数据库中。
首先,让我们暂时将其视作调试或试验,创建一个针对用户名为yuno_miyako的用户的帖子内容集合。顺便考虑一下img文件的命名方式。目前我正在将图像放入img文件夹中,但是我们需要对每个用户进行分类,并且图像的文件名也必须是唯一的,否则无法进行搜索。
因此,我们决定将文件名设置为“id_文件名”。我认为这样可以唯一确定…
#デバッグ用にyuno_miyakoには画像とコメントを加えておく
@app.route("/debug/yuno_miyako")
def database(mongodb):
#yuno_miyakoが存在するか確認
query = mongodb["userinfo"].find({"userID": "yuno_miyako"})
if query.count() == 0 : mongodb["userinfo"].insert_one( {"userID" : "yuno_miyako" } )
query = mongodb["userinfo"].find_one({"userID": "yuno_miyako"})
userdbID = query["_id"]
entry = mongodb["entry"].find({"userdbID" : userdbID})
if entry.count() == 0 :
#testimgから3枚画像を引っ張ってきてそれを登録する。testimgの名前に+entryIDを加えてimgに移動する
texts = ["シャネルのバッグです" , "すっご〜〜い" , "そら 綺麗"]
imgs = os.listdir("./testimg")
for i in range(3) :
entryID = mongodb["entry"].insert_one(
{"userdbID" : userdbID , "imgfilename" : imgs[i] , "comment" : texts[i]}
).inserted_id
shutil.copy("./testimg/"+imgs[i] , "./img/"+str(entryID)+ "_" + imgs[i])
return "登録完了"
else :
return "すでに何かがcontentsに登録されています"
8. 在HTML中显示
修改Python代码以显示用户页面。
以前,我们直接传递了注释,但现在决定从”投稿内容”集合中提取信息并传递(也许直接传递“entry”更好…稍后考虑)。
#USER PAGE
@app.get("/<userID>")
def userpage(userID , mongodb) :
userdbID = methods.userdbID_from_userID(userID, mongodb)
entry = mongodb["entry"].find({"userdbID" : userdbID})
contents = []
for q in entry :
entryID = q["_id"]
imgfilename = q["imgfilename"]
comment = q["comment"]
contents.append({"entryID" : entryID , "imgfilename" : imgfilename , "comment" : comment})
return template("userpage" , userID = userID , contents = contents)
通过修改HTML代码,成功显示出来了。
%for i in range(0,3) :
<div class="col-lg-6 mb-5">
<div class="card lg-6 box-shadow" >
<img class="card-img-top" src="../img/{{str(contents[i]['entryID'])+'_'+contents[i]['imgfilename']}}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">@{{userID}}</h5>
<p class="card-text">{{contents[i]['comment']}}</p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-secondary">View</button>
<button type="button" class="btn btn-sm btn-outline-secondary">Edit</button>
</div>
<small class="text-muted">9 mins</small>
</div>
</div>
</div>
</div>
%end
9. 总结
雖然外觀與上次完全相同,但我們已經將它連接到了mongoDB,並且可以從外部數據庫中擷取圖片文件的名稱和評論。在開發過程中,我們更改了一些變量名(例如,username更改為userID),使其變得不再容易理解。這讓我有點擔心。下一步,我們希望實際上能夠上傳圖片並發布文章。