Day 057
Udemy Python Bootcamp Day 057
Using Jinja to Produce Dynamic HTML Pages
Jinja
The HTML files can actually act as a template as long as we know how to work with a templating language. The tmplating languagethat we're going to use is called Jinja.
It allows us to use some syntax like
{}
, %
, or {{}}
in order to specify inside the HTML file which parts should actually be evaluated as Python code.<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Website</title>
</head>
<body>
<h1>Hello, World!</h1>
<h2>{{ 5 * 6 }}</h2>
</body>
</html>
from flask import Flask, render_template
import random
import datetime
app = Flask(__name__)
@app.route('/')
def home():
random_number = random.randint(1, 10)
current_year = datetime.datetime.now().year
return render_template("index.html", num=random_number, year=current_year)
if __name__ == "__main__":
app.run(debug=True)
The most important thing is I want to be able to send this random number over to my index.html
and incorporate it into this template when I render it.<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Website</title>
</head>
<body>
<h1>Hello, World!</h1>
<h2>{{ 5 * 6 }}</h2>
<h3>Random number: {{ num }}</h3>
</body>
<footer>
<p>©Copyright {{ year }}. Built by Awesome Kim.</p>
</footer>
</html>
Combining Jinja Templating with APIs
guess.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Guess</title>
</head>
<body>
<h1>Hey {{ name.title() }},</h1>
<h2>I think you are {{ gender }}</h2>
<h3>And maybe {{ age }} years old.</h3>
</body>
</html>
.py
import requests
AGE_ENDPOINT = "https://api.agify.io/?name="
GENDER_ENDPOINT = "https://api.genderize.io/?name="
@app.route('/guess/<name>')
def guess(name):
gender_response = requests.get(GENDER_ENDPOINT + name)
gender = gender_response.json()["gender"]
age_response = requests.get(AGE_ENDPOINT + name)
age = age_response.json()["age"]
return render_template("guess.html", name=name, gender=gender, age=age)
本当に気が狂った.やった...
Multiline Statements with Jinja
@app.route('/blog')
def blog():
blog_url = "https://api.npoint.io/2fa8f877104b260d1b8b"
response = requests.get(blog_url)
all_posts = response.json()
return render_template("blog.html", posts=all_posts)
blog.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blog</title>
</head>
<body>
{% for blog_post in posts: %}
<h1>{{ blog_post["title"] }}</h1>
<h2>{{ blog_post["subtitle"] }}</h2>
{% endfor %}
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blog</title>
</head>
<body>
{% for blog_post in posts: %}
{% if blog_post["id"] == 2: %}
<h1>{{ blog_post["title"] }}</h1>
<h2>{{ blog_post["subtitle"] }}</h2>
{% endif %}
{% endfor %}
</body>
</html>
URL Building with Flask
@app.route('/blog/<num>')
def get_blog(num):
print(num)
blog_url = "https://api.npoint.io/2fa8f877104b260d1b8b"
response = requests.get(blog_url)
all_posts = response.json()
return render_template("blog.html", posts=all_posts)
index.html
<a href="{{ url_for('get_blog', num=3) }}">Go To Blog</a>
Blog Capstone Project Part 1 - Templating
そうするのは難しくない.
Read
ボタンを押して他のルーティングを呼び出すのに完全に失敗しましたindex.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://fonts.googleapis.com/css2?family=Raleway" rel="stylesheet">
<link rel="stylesheet" href="../static/css/styles.css">
</head>
<body>
<div class="wrapper">
<div class="top">
<div class="title"><h1>My Blog</h1></div>
</div>
{% for post in posts: %}
<div class="content">
<div class="card">
<h2>{{ post["title"] }}</h2>
<p>{{ post["subtitle"] }}</p>
<a href="{{ url_for('show_post', index=post.id) }}">Read</a>
</div>
</div>
{% endfor %}
</div>
</body>
<footer>
<p>Made with ♥️ in London.</p>
</footer>
</html>
index.html
からhref="{{ url_for('show_post', index=post.id) }}"
とは想像できませんが...htmlからurlを呼び出すときのmain.pyの関数を読み込むことができます
main.py
from flask import Flask, render_template
import requests
from post import Post
posts = requests.get("https://api.npoint.io/e82dfd36fe5719f2df6f").json()
post_objects = [Post(post["id"], post["title"], post["subtitle"], post["body"]) for post in posts]
app = Flask(__name__)
@app.route('/')
def home():
return render_template("index.html", posts=posts)
@app.route('/post/<int:index>')
def show_post(index):
requested_post = None
for blog_post in post_objects:
if blog_post.id == index:
requested_post = blog_post
return render_template("post.html", post=requested_post)
if __name__ == "__main__":
app.run(debug=True)
posts
の項目をリストにして使うとは思わなかった.実際、私もなぜ
def show_post(index)
がそう書いたのか完全に理解していません.なぜ
id
と呼んだのか分かりません.+) 2022.04.06
blog_post.id
クラスが呼び出されると属性値が返されるため、このように記述される.つまり、たぶん今回のプロジェクトは大変だったのかな・・・
Post()
class Post:
def __init__(self, post_id, title, subtitle, body):
self.id = post_id
self.title = title
self.subtitle = subtitle
self.body = body
同様に、OOPを記述するも、このように値post.py
のみが呼び出され、__init__
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://fonts.googleapis.com/css2?family=Raleway" rel="stylesheet">
<link rel="stylesheet" href="../static/css/styles.css">
</head>
<body>
<div class="wrapper">
<div class="top">
<div class="title"><h1>My Blog</h1></div>
</div>
<div class="content">
<div class="card">
<h1>{{ post.title }}</h1>
<h2>{{ post.subtitle }}</h2>
<p>{{ post.body }}</p>
</div>
</div>
</div>
</body>
<footer>
<p>Made with ♥️ in London.</p>
</footer>
</html>
Reference
この問題について(Day 057), 我々は、より多くの情報をここで見つけました https://velog.io/@awesomee/Day-057テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol