跟着麦叔学flask,感谢b站麦叔
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
**/__pycache__
|
||||
**/*.db
|
||||
**/*.sql
|
||||
**/*.db.back
|
||||
databases/*
|
||||
29
blueprint/blog_views.py
Executable file
29
blueprint/blog_views.py
Executable file
@@ -0,0 +1,29 @@
|
||||
from flask import Blueprint, render_template
|
||||
from database import get_owp_db
|
||||
import os
|
||||
|
||||
|
||||
blog_bp = Blueprint('blog', __name__)
|
||||
|
||||
@blog_bp.route('/')
|
||||
def home():
|
||||
db = get_owp_db()
|
||||
return render_template('home.html')
|
||||
|
||||
@blog_bp.route('/about/')
|
||||
def about():
|
||||
return render_template('about.html')
|
||||
pass
|
||||
|
||||
@blog_bp.route('/db_test/')
|
||||
def test_db():
|
||||
db = get_owp_db()
|
||||
|
||||
try:
|
||||
cur = db.execute('SELECT sqlite_version();')
|
||||
ver = cur.fetchone()[0]
|
||||
return f"数据库连接成功!SQLite 版本是: {ver}"
|
||||
except Exception as e:
|
||||
return f"连接失败: {str(e)}"
|
||||
|
||||
|
||||
95
blueprint/study_views.py
Executable file
95
blueprint/study_views.py
Executable file
@@ -0,0 +1,95 @@
|
||||
from flask import Blueprint, render_template, request, url_for, flash, redirect
|
||||
import os
|
||||
import sqlite3
|
||||
|
||||
study_bp = Blueprint('study', __name__)
|
||||
|
||||
def get_db_conn():
|
||||
conn = sqlite3.connect('/var/open-ww3-project-ww3-tw/databases/database.db')
|
||||
conn.row_factory = sqlite3.Row
|
||||
return conn
|
||||
|
||||
def get_posts(posts_id):
|
||||
conn = get_db_conn()
|
||||
posts = conn.execute("SELECT *, datetime(created, '+8 hours') AS created_8 FROM posts WHERE id = ?", (posts_id,)).fetchone()
|
||||
conn.close()
|
||||
return posts
|
||||
|
||||
@study_bp.route('/')
|
||||
def home():
|
||||
conn = get_db_conn()
|
||||
sql = "SELECT *, datetime(created, '+8 hours') AS created_8 FROM posts;"
|
||||
posts = conn.execute(sql).fetchall()
|
||||
conn.close()
|
||||
return render_template('study/home.html', posts=posts[::-1])
|
||||
|
||||
@study_bp.route('/about/')
|
||||
def about():
|
||||
return render_template('study/about.html')
|
||||
|
||||
@study_bp.route('/posts/<int:posts_id>')
|
||||
def show_posts_id(posts_id):
|
||||
conn = get_db_conn()
|
||||
posts = get_posts(posts_id)
|
||||
if posts is None:
|
||||
return '抱歉,未查到该文章'
|
||||
|
||||
return render_template('study/posts.html', posts=posts)
|
||||
|
||||
@study_bp.route('/posts/new/', methods=('GET', 'POST'))
|
||||
def new():
|
||||
if request.method == "POST":
|
||||
title = request.form['title']
|
||||
content = request.form['content']
|
||||
|
||||
if not title:
|
||||
flash('标题不能为空')
|
||||
elif not content:
|
||||
flash('内容不能为空')
|
||||
else:
|
||||
conn = get_db_conn()
|
||||
conn.execute('insert into posts (title, content) values (?, ?)', (title, content))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
flash('文章发布成功')
|
||||
return redirect(url_for('study.home'))
|
||||
|
||||
return render_template('study/new.html')
|
||||
|
||||
@study_bp.route('/posts/<int:posts_id>/edit', methods=('GET', 'POST'))
|
||||
def edit_posts_id(posts_id):
|
||||
if request.method == "POST":
|
||||
title = request.form['title']
|
||||
content = request.form['content']
|
||||
|
||||
if not title:
|
||||
flash('标题不能为空')
|
||||
elif not content:
|
||||
flash('内容不能为空')
|
||||
else:
|
||||
conn = get_db_conn()
|
||||
conn.execute('update posts set title= ?, content = ? where id = ?', (title, content, posts_id))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return redirect(url_for('study.home'))
|
||||
|
||||
return render_template('study/edit.html', posts=posts)
|
||||
|
||||
@study_bp.route('/posts/<int:posts_id>/delete/', methods=['POST' , 'GET'])
|
||||
def delete_posts_id(posts_id):
|
||||
if request.method == "POST":
|
||||
posts = get_posts(posts_id)
|
||||
conn = get_db_conn()
|
||||
conn.execute('DELETE FROM posts WHERE id = ?', (posts_id,))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
flash('删除成功')
|
||||
return redirect(url_for('study.home'))
|
||||
|
||||
elif request.method == "GET":
|
||||
posts = get_posts(posts_id)
|
||||
conn = get_db_conn()
|
||||
conn.execute('DELETE FROM posts WHERE id = ?', (posts_id,))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return render_template('study/delete.html', posts=posts)
|
||||
11
database.py
Executable file
11
database.py
Executable file
@@ -0,0 +1,11 @@
|
||||
import sqlite3
|
||||
from flask import g
|
||||
|
||||
DATABASE_owp = '/var/databases/sqlite/owp.db'
|
||||
|
||||
def get_owp_db():
|
||||
db = getattr(g, '_database', None)
|
||||
if db is None:
|
||||
db = g._database = sqlite3.connect(DATABASE_owp)
|
||||
db.row_factory = sqlite3.Row
|
||||
return db
|
||||
39
main.py
Executable file
39
main.py
Executable file
@@ -0,0 +1,39 @@
|
||||
from flask import Flask, render_template, redirect, url_for, g
|
||||
from blueprint.blog_views import blog_bp
|
||||
from blueprint.study_views import study_bp
|
||||
# from blueprint.admin_views import admin_bp
|
||||
import os
|
||||
|
||||
app = Flask(__name__, static_url_path='/static/')
|
||||
|
||||
# session
|
||||
#app.secret_key = "508948973a8651f160baf3b26f18c47d"
|
||||
app.secret_key = '玩鵬畝遜溉痕叛課還擇鼇粹拜溜泉聰倡效蘭鱅都凍芝西鄂'
|
||||
|
||||
|
||||
|
||||
# 注册蓝图
|
||||
app.register_blueprint(blog_bp, url_prefix='/blog')
|
||||
app.register_blueprint(study_bp, url_prefix='/study')
|
||||
# app.register_blueprint(admin_bp, url_prefix='/admin')
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def repage():
|
||||
# return '<meta http-equiv="refresh" content="0.1;url=/blog/">'
|
||||
return redirect(url_for('study.home'))
|
||||
|
||||
|
||||
@app.route('/greet/<name>/')
|
||||
def greet(name):
|
||||
return f'Hello, {name}!'
|
||||
|
||||
# 全局清理关闭数据库连接
|
||||
@app.teardown_appcontext
|
||||
def close_connection(exception):
|
||||
db = getattr(g, '_database', None)
|
||||
if db is not None:
|
||||
db.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host="0.0.0.0", port=8085, debug=True)
|
||||
58
static/css/main.css
Executable file
58
static/css/main.css
Executable file
@@ -0,0 +1,58 @@
|
||||
/* css页面蓝图 */
|
||||
|
||||
/* 外部背景 */
|
||||
html, body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0; /*外边框*/
|
||||
padding: 0; /*内边框*/
|
||||
overflow: hidden; /* 防止滚动条 */
|
||||
background-color: #333; /* 背景颜色 */
|
||||
}
|
||||
|
||||
/* 内部容器 */
|
||||
#app-canvas {
|
||||
width: 1280px;
|
||||
height: 800px;
|
||||
|
||||
background-color: rgba(147, 185, 255, 0.644);
|
||||
border: 5px solid #0056b3; /* 定义边框 5px 实线 蓝色 */
|
||||
/* transform-origin: 0 0; /* 定义缩放起点 左上角 */
|
||||
|
||||
position:fixed; /* 固定页面,不滚动 */
|
||||
left: 50%; /* 调整左边缘位置到中央 */
|
||||
top: 50%; /* 调整上边缘位置到中央 */
|
||||
|
||||
padding: 30px; /* 内部间距 30px */
|
||||
|
||||
|
||||
}
|
||||
|
||||
header {
|
||||
margin-bottom: 30px; /* 外部间距 30px */
|
||||
text-align: center; /* 文字居中 */
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 48px;
|
||||
color: #fff;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
#content-area {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
gap: 40px;
|
||||
}
|
||||
|
||||
/* 自带 */
|
||||
.box {
|
||||
width: 500px;
|
||||
height: 600px;
|
||||
background-color: #ffffffcc;
|
||||
border: 1px solid #ccc;
|
||||
padding: 20px;
|
||||
font-size: 20px;
|
||||
text-align: left;
|
||||
overflow: auto;
|
||||
}
|
||||
6
static/css/style.css
Executable file
6
static/css/style.css
Executable file
@@ -0,0 +1,6 @@
|
||||
h1 {
|
||||
border: 2px;
|
||||
color:brown;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
BIN
static/icon/original.ico
Executable file
BIN
static/icon/original.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 268 KiB |
BIN
static/img/my_girl.png
Executable file
BIN
static/img/my_girl.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
BIN
static/img/open-ww3-project.png
Executable file
BIN
static/img/open-ww3-project.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 280 KiB |
29
static/js/main.js
Executable file
29
static/js/main.js
Executable file
@@ -0,0 +1,29 @@
|
||||
// js目前不会,先靠ai
|
||||
|
||||
function resizeCanvas() {
|
||||
// 定义设计基准尺寸
|
||||
const designWidth = 1280;
|
||||
const designHeight = 800;
|
||||
|
||||
// 获取当前浏览器视口尺寸
|
||||
const currentWidth = window.innerWidth;
|
||||
const currentHeight = window.innerHeight;
|
||||
|
||||
const canvas = document.getElementById('app-canvas');
|
||||
|
||||
// 计算缩放比例
|
||||
const scaleX = currentWidth / designWidth;
|
||||
const scaleY = currentHeight / designHeight;
|
||||
const scaleFactor = Math.min(scaleX, scaleY);
|
||||
|
||||
// 确保元素中心与 left: 50%; top: 50%; 对齐
|
||||
canvas.style.transform = `translate(-50%, -50%) scale(${scaleFactor})`;
|
||||
}
|
||||
|
||||
// 首次加载时执行
|
||||
document.addEventListener('DOMContentLoaded', resizeCanvas);
|
||||
// 监听窗口大小变化时执行,保持动态缩放
|
||||
window.addEventListener('resize', resizeCanvas);
|
||||
|
||||
// 确保在某些情况下也能正确初始化
|
||||
resizeCanvas();
|
||||
13
templates/about.html
Executable file
13
templates/about.html
Executable file
@@ -0,0 +1,13 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>不想写了</title>
|
||||
<meta charset="utf-8" lang="zh-CN">
|
||||
</head>
|
||||
<body>
|
||||
忘记写了
|
||||
<br>
|
||||
所以暂时就不写了
|
||||
<p>2025.08.05</p>
|
||||
<p>over</p>
|
||||
</body>
|
||||
</html>
|
||||
245
templates/home.html
Executable file
245
templates/home.html
Executable file
@@ -0,0 +1,245 @@
|
||||
<!-- 主页 -->
|
||||
<html>
|
||||
<head>
|
||||
<title>首页 | ww3</title>
|
||||
<meta charset="utf-8" lang="zh-CN">
|
||||
<link rel="icon" type="image/x-icon" href="/static/icon/original.ico">
|
||||
<!-- 引入页面蓝图css -->
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app-canvas">
|
||||
<header>
|
||||
<h1 style="margin: 80px 0 0 0; color:aqua;">open-ww3-project</h1>
|
||||
</header>
|
||||
<!-- 导航栏 -->
|
||||
<div id="navbar1">
|
||||
<table border="0" style="background-color: rgba(147, 185, 255, 0.644);">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td id="td_navbar_40px"><b><a href="https://ww3.tw/" id="url_">首页</a></b></td>
|
||||
<td id="td_navbar_40px"><b><a href="https://ww3.tw/blog/about/" id="url_">关于</a></b></td>
|
||||
<td id="td_navbar_40px"><b><a href="https://ww3.tw/blog/post/" id="url_">文章</a></b></td>
|
||||
<td id="td_navbar_75px"><b><a href="https://ww3.tw/jumping-message/" id="url_">弹幕留言</a></b></td>
|
||||
<td id="td_navbar_78px"><b><a href="https://ww3.tw/short-url/" id="url_">短链生成</a></b></td>
|
||||
<td id="td_navbar_52px"><b><a href="https://gitea.ww3.tw/skimrme/" id="url_">gitea</a></b></td>
|
||||
<td id="td_navbar_160px"><b><a href="https://ww3.tw/docker-registry/" id="url_">docker-registry</a></b></td>
|
||||
<td id="td_navbar_40px"><b><a href="https://api.ww3.tw/" id="url_">api</a></b></td>
|
||||
<td id="td_navbar_40px"><b><a href="https://wiki.ww3.tw/" id="url_">wiki</a></b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- 倒过来的箱子 真不明白,为什么我会称呼箱子为open-ww3-project-->
|
||||
<div style="margin: 80px -30px -100px 180px;">
|
||||
<img id="open-ww3-project-img" width="10%" src="/static/img/open-ww3-project.png" alt="open-ww3-project-img">
|
||||
</div>
|
||||
<!-- gitea 图标 -->
|
||||
<a style="background-color: blueviolet; position: absolute;" href="https://gitea.ww3.tw/skimrme/open-ww3-project-ww3-tw">
|
||||
<img id="gitea-img" src="https://gitea.ww3.tw/assets/img/logo.svg" width="150px" alt="gitea" >
|
||||
</a>
|
||||
|
||||
<!-- 导航栏 -->
|
||||
<div id="content-area">
|
||||
<!-- 屑站日志 -->
|
||||
<h3 style="margin: 70px 0 30px -50px;">屑站日志:<br></h3>
|
||||
<div id="logs">
|
||||
<font size="3.2">
|
||||
<table border="0">
|
||||
<tbody>
|
||||
<?php
|
||||
// 引入数据库 sqlite
|
||||
include "./logs.php.text";
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</font>
|
||||
</div>
|
||||
<!-- 屑站日志 -->
|
||||
|
||||
<div id="post_content">
|
||||
<?php
|
||||
//include "post/index.php";
|
||||
// 设定数据库路径
|
||||
$db_path = '/var/www/owp/open-ww3-project-ww3-tw/databases/sqlite/owp.db';
|
||||
|
||||
try {
|
||||
// 连接数据库
|
||||
$db = new SQLite3($db_path);
|
||||
// 连接成功输出连接成功
|
||||
echo "<!--数据库连接成功-->";
|
||||
// 如果连接成功,但是内部状态有问题
|
||||
if ($db->lastErrorCode() !==0) {
|
||||
// 依旧显示为连接失败
|
||||
die("数据库连接失败");
|
||||
}
|
||||
|
||||
// 内容区
|
||||
// 执行sql命令 查询表单
|
||||
$select_id_date_title_from_posts_btos /*查询posts表单中的id date title id从大到小排列*/ = $db->query('SELECT id, date, title FROM posts ORDER BY id DESC'); // 执行查询posts表单中的id date title id从大到小排列的命令
|
||||
// 循环 写入
|
||||
|
||||
echo "<center><b><h2>全部文章</h2></b></center>";
|
||||
echo "<br>";
|
||||
echo "文章如下↓";
|
||||
echo "<br>";
|
||||
echo "<br>";
|
||||
|
||||
while ($row = $select_id_date_title_from_posts_btos->fetchArray(SQLITE3_ASSOC)) {
|
||||
|
||||
echo "文章id: " . $row['id'] . "<br>";
|
||||
echo $row['date'] . " " . "文章标题: " . $row['title'] . "<br>";
|
||||
echo "<a href='https://ww3.tw/blog/post/s/?id=" . $row['id'] . "'>页面跳转</a><br><br>";
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 关闭数据库连接
|
||||
$db->close();
|
||||
|
||||
// 捕获php报错
|
||||
} catch (Exception $e) {
|
||||
// 依旧显示为连接失败
|
||||
die("数据库连接失败");
|
||||
// 关闭数据库连接
|
||||
$db->close();
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 私の娘 -->
|
||||
<div id="my_girl" style="margin: -40px 0 0 1100px;"></div>
|
||||
<!-- 私の娘 -->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
<!-- css 部分 -->
|
||||
<style>
|
||||
#navbar1 {
|
||||
margin: -160px 0 100px -30px;
|
||||
}
|
||||
#url_
|
||||
{
|
||||
text-decoration: none;
|
||||
color: rgb(0, 0, 0);
|
||||
font-size: 18.8px;
|
||||
}
|
||||
#td_navbar_40px
|
||||
{
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
#td_navbar_52px
|
||||
{
|
||||
width: 52px;;
|
||||
}
|
||||
|
||||
#td_navbar_78px
|
||||
{
|
||||
width: 78px;
|
||||
}
|
||||
|
||||
#td_navbar_160px
|
||||
{
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
/* 日志 */
|
||||
#logs
|
||||
{
|
||||
height: 220px;
|
||||
width: 450px;
|
||||
overflow: auto;
|
||||
background: #ffffffbc;
|
||||
/* up、right、down、left */
|
||||
margin: 115px 0px 0px -280px;
|
||||
}
|
||||
|
||||
#td_logs
|
||||
{
|
||||
width: 75px;
|
||||
padding-top: 1.8px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#td_logs_content
|
||||
{
|
||||
color: rgb(132, 132, 132);
|
||||
padding-left: 10px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
/* 日志 */
|
||||
|
||||
/* 文章 */
|
||||
#post_content
|
||||
{
|
||||
/*text-align: center;*/
|
||||
height: 500px;
|
||||
width: 490px;
|
||||
color: rgb(202, 202, 202);
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||
background-color: rgba(27, 27, 27, 0.010);
|
||||
overflow: auto;
|
||||
font-size: 19px;
|
||||
/* up、right、down、left */
|
||||
margin: 40px 0 0 0;
|
||||
}
|
||||
|
||||
/* 图标 */
|
||||
#open-ww3-pro1ject-img
|
||||
{
|
||||
overflow: auto;
|
||||
/* up、right、down、left */
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
|
||||
#gitea-img
|
||||
{
|
||||
margin: -150px 0 0 1150px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
<!-- js 部分-->
|
||||
<script src="/static/js/main.js"> 引入js页面蓝图 </script>
|
||||
|
||||
<!-- 私の娘 -->
|
||||
<!-- https://cdn.jsdelivr.net/npm/sakana-widget@2.7.1/lib/sakana.min.css -->
|
||||
<!-- https://cdn.jsdelivr.net/npm/sakana-widget@2.7.1/lib/sakana.min.js -->
|
||||
<!-- https://cdnjs.cloudflare.com/ajax/libs/sakana-widget/2.7.1/sakana.min.css -->
|
||||
<!-- https://cdnjs.cloudflare.com/ajax/libs/sakana-widget/2.7.1/sakana.min.js -->
|
||||
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/sakana-widget@2.7.1/lib/sakana.min.css"
|
||||
/>
|
||||
|
||||
<script>
|
||||
function initSakanaWidget(){
|
||||
const customImageUrl = 'https://open-ww3-project.ww3.tw/blog/src/img/my_girl.png';
|
||||
const baseCharacter = SakanaWidget.getCharacter('chisato');
|
||||
const myCharacter = {
|
||||
image: customImageUrl,
|
||||
initialState: baseCharacter.initialState,
|
||||
};
|
||||
|
||||
SakanaWidget.registerCharacter('my_girl', myCharacter);
|
||||
new SakanaWidget({
|
||||
character: 'my_girl',
|
||||
size: 200,
|
||||
autoFit: true,
|
||||
controls: true
|
||||
}).mount('#my_girl');
|
||||
}
|
||||
</script>
|
||||
|
||||
<script
|
||||
async
|
||||
onload="initSakanaWidget()"
|
||||
src="https://cdn.jsdelivr.net/npm/sakana-widget@2.7.1/lib/sakana.min.js">
|
||||
</script>
|
||||
<!-- 私の娘 -->
|
||||
12
templates/study/about.html
Executable file
12
templates/study/about.html
Executable file
@@ -0,0 +1,12 @@
|
||||
{# 引入base #}
|
||||
{% extends 'study/base.html' %}
|
||||
|
||||
{# 网站标签 #}
|
||||
{% block title %} 关于页面 {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
大家好......
|
||||
没有了
|
||||
|
||||
{% endblock %}
|
||||
54
templates/study/base.html
Executable file
54
templates/study/base.html
Executable file
@@ -0,0 +1,54 @@
|
||||
{# base模板 #}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" lang="zh_CN">
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
<!--link rel="stylesheet" href="/static/css/style.css"-->
|
||||
{# 建立一个url,来源于static文件夹的,文件名字为css文件夹下的style.css #}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
<div style="width: 100%; background-color: rgb(122, 91, 246);">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="url">
|
||||
<a href="/study" class="url">home</a>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="url">
|
||||
<!--a href="/study/about" class="url">about</a-->
|
||||
<a href="{{ url_for('study.about')}}" class="url">about</a>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="url">
|
||||
<a href="/study/posts/new" class="url">新建文章</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% for message in get_flashed_messages() %}
|
||||
<div>{{ message }}</div>
|
||||
{% endfor %}
|
||||
|
||||
{% block content %} {% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<style>
|
||||
body {
|
||||
margin: 0 0 0 0;
|
||||
background-color: rgb(157, 209, 255);
|
||||
}
|
||||
|
||||
.url {
|
||||
height: 40px;
|
||||
margin: 10px 0 0 10px;
|
||||
color: rgb(0, 0, 0);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
5
templates/study/delete.html
Executable file
5
templates/study/delete.html
Executable file
@@ -0,0 +1,5 @@
|
||||
<b>确定要删除 "{{ posts['title'] }}" 吗?</b>
|
||||
|
||||
<form action="{{ url_for('study.delete_posts_id', posts_id=posts['id']) }}" method="post">
|
||||
<input type="submit" value="删除文章" class="btn btn-danger htn-sm" onclick="return confirm('确定要删除吗')">
|
||||
</form>
|
||||
25
templates/study/edit.html
Executable file
25
templates/study/edit.html
Executable file
@@ -0,0 +1,25 @@
|
||||
{# 引入base #}
|
||||
{% extends 'study/base.html' %}
|
||||
|
||||
{# 网站标签 #}
|
||||
{% block title %} 编辑 "{{ posts['title'] }}" {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label for="title">标题</label>
|
||||
<input type="text" name="title" placeholder="标题" class="form-control" value="{{ request.form['title'] or posts['title'] }}">
|
||||
</inpit>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="content">内容</label>
|
||||
<textarea name="content" placeholder="文章内容" class="form-control">{{ request.form['content'] or posts['content'] }}</textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary">提交</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
20
templates/study/home.html
Executable file
20
templates/study/home.html
Executable file
@@ -0,0 +1,20 @@
|
||||
{# 引入base #}
|
||||
{% extends 'study/base.html' %}
|
||||
|
||||
{# 网站标签 #}
|
||||
{% block title %}study学习{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>学习如何搭建一个blog</h1>
|
||||
<h2>欢迎访问一个学习如何搭建一个blog的页面</h2>
|
||||
|
||||
{% for posts in posts %}
|
||||
<a href="/study/posts/{{ posts['id'] }}">
|
||||
<!--a href="{{ url_for('study.show_posts_id', posts_id=posts['id']) }}"-->
|
||||
<h2>{{ posts['title'] }}</h2>
|
||||
</a>
|
||||
<span>{{ posts['created_8'] }}</span>
|
||||
<hr>
|
||||
<br>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
25
templates/study/new.html
Executable file
25
templates/study/new.html
Executable file
@@ -0,0 +1,25 @@
|
||||
{# 引入base #}
|
||||
{% extends 'study/base.html' %}
|
||||
|
||||
{# 网站标签 #}
|
||||
{% block title %} 新建文章 {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label for="title">标题</label>
|
||||
<input type="text" name="title" placeholder="标题" class="form-control" value="{{ request.form['title'] }}">
|
||||
</inpit>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="content">内容</label>
|
||||
<textarea name="content" placeholder="文章内容" class="form-control">{{ request.form['content'] }}</textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary">提交</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
19
templates/study/posts.html
Executable file
19
templates/study/posts.html
Executable file
@@ -0,0 +1,19 @@
|
||||
{# 引入base #}
|
||||
{% extends 'study/base.html' %}
|
||||
|
||||
{# 网站标签 #}
|
||||
{% block title %} {{ posts['title'] }} {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ posts['title'] }}</h1>
|
||||
<span>{{ posts['created_8'] }}</span>
|
||||
<a href="./{{ posts['id'] }}/edit">
|
||||
<span>编辑</span>
|
||||
</a>
|
||||
<hr>
|
||||
|
||||
<p>{{ posts['content'] }}</p>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user