与超级英雄API合作
应用程序编程接口是一种软件中间件,它位于两个应用程序之间,允许它们进行通信和交换数据。
因此,这种中间软件能够在两个应用程序之间进行数据传输。例如,其他软件可以使用一个API来与一个特定的框架通信。
超级英雄API是一个应用编程接口,提供关于漫画宇宙中的超级英雄列表的数据和信息。
这包括他们的身体能力、传记信息、职业、力量统计、与其他英雄的联系以及在电影中的出现。
本文通过在一个Django应用程序中消费其数据来探索超级英雄的API。首先,我们将创建一个Django应用程序,列出漫画世界中所有的超级英雄。每个超级英雄都会有自己的页面来展示他的特点。
前提条件
- 代码编辑器,最好是[Visual Studio Code]。
- 对[Django]框架的良好理解。
- [超级英雄的API密钥]。
- 对[CSS]和[HTML]有一些基本的了解。
项目设置
每个Django项目都需要其虚拟环境来存储项目的所有需求和依赖性。
出于这个原因,我们将为我们的项目创建一个虚拟环境。执行下面的命令来创建一个虚拟环境,并将其称为superhero 。
virtualenv superhero
接下来,将目录改为包含虚拟环境的文件夹,然后用下面的命令启动虚拟环境。
source superhero/bin/activate
安装Django
现在我们已经激活了虚拟环境,我们需要在虚拟环境中安装Django以及所有其他使用该应用程序所需的依赖项。
执行下面的命令来安装Django。
pip install Django
该命令负责使用Pip获取Django软件包,并将其安装在虚拟环境中。
接下来,执行下面的命令,在当前工作目录下创建一个新的Django项目。
Django-admin startproject superheroes
现在的项目文件夹结构应该如下图所示。
├── superheroes
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── .superhero/
在下一步,我们将安装requests 。Requests 是一个简单的HTTP库,用于使用Python发送HTTP请求。
这个库允许人们向HTTP请求传递不同的参数,包括头文件、表单数据和多部分文件。此外,它还可以让人们从JSON格式的请求中获取响应数据。
在终端运行以下命令来安装requests 库。
pip install requests
然后,我们可以运行pip freeze > requirements.txt ,将虚拟环境中的所有需求复制到一个名为requirements.txt 的新文件。
创建应用程序
成功执行上述步骤后,我们需要使用Django命令创建应用程序。
Django中的应用程序是主项目的子项目。因此,举例来说,一个网站可能有news ,作为一个独立的应用程序,而不是portfolio 。对Django来说,这可能是两个不同的子应用程序。
要创建一个应用程序,请执行以下命令。
django-admin startapp heroes
该命令将创建一个新的heroes 应用程序,包括视图、模型、URL、模板和迁移。该应用程序的文件夹概览如下所示。
├── heroes
│ ├── __pycache__
│ ├── migrations
│ ├── templates
│ ├── __init__.py
│ ├── admin.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
关于URL的工作
通用资源定位器是指定系统中特定资源的路径。全站的导航在url.py 文件中。
一旦指定了一个URL,要执行的函数就会从view.py 文件中获取。
这个函数告诉Django要渲染的模板的位置。我们将有两个路径,分别指定默认主页和一个英雄页面。
在urls.py 文件中,添加以下片段。
from Django.URLs import path
from . import views
from Django.conf import settings
from Django.conf.URLs.static import static
urlpatterns = [
path('', views.homepage, name='index'),
path('single-hero/<int:id>', views.single_hero, name='single-hero'),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
single-hero 路径有一个额外的参数<int:id> ,它指定了超级英雄的ID,其细节将被查看。
在视图上工作
views.py 文件包含了所有在访问特定路径时要执行的函数。由于我们使用requests 和render方法,我们需要将它们导入到views.py 文件中。
from Django.shortcuts import render
import requests
我们在这个文件中会有两个函数。第一个函数将是homepage() 。这个函数将接收请求并使用requests 库从API网址中获取所有的超级英雄。接下来,它将超级英雄的列表转换为json,然后将其传递给模板渲染。
def homepage(request):
res = requests.get('https://akabab.github.io/superhero-api/api/all.json')
heroes = res.json()
context = {'heros': heroes}
return render(request, 'homepage.html', context)
下一个函数将被称为single_hero ,它也处理请求和一个特定超级英雄的ID。
我们可以按照相同的网址,但用不同的ID来获取其他超级英雄的详细信息。检索到超级英雄的数据后,响应被转换为JSON,传递给single-hero.html 模板。
def single_hero(request, id):
response = requests.get(f"https://akabab.github.io/superhero-api/api/id/{id}.json")
response.raise_for_status() # raises exception when not a 2xx response
if response.status_code != 204:
hero = response.json()
context = {'hero': hero}
return render(request, 'single-hero.html', context)
在模板上工作
模板包含将被渲染的用户界面文件。我们正在设计三个模板文件,其中包括从视图传来的数据。
第一个文件将包含所有页面的统一组件,如导航栏和页脚,而其余两个文件将根据它们显示的数据而变化。
基础模板
基本模板包含所有页面所需的片段。此外,我们还指定了我们的项目所需的CSS和JavaScript文件的链接。
所有其他模板都是对基础模板的扩展。创建一个名为base.html 的新文件,然后添加下面的片段。
{% load static %}
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="{% static 'main.css' %}">
<link rel="stylesheet" href="{% static 'det.css' %}">
<link rel="stylesheet" href="{% static 'fav.css' %}">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<title>Home</title>
</head>
<body>
<header>
<div class="app-name center"><a href='index.html'>SuperHeroApp</a></div>
</header>
{% block content %}
<!-- Begin Page Content -->
<!-- /.container-fluid -->
{% endblock %}
<script type="text/javascript" src="../scripts/index.js"></script>
</body>
</html>
所有超级英雄模板
这个模板是包含所有超级英雄的列表、他们的名字以及访问各个超级英雄的链接的html文件。首先,在templates 文件夹中创建一个名为homepage.html 的新文件。在该文件中,添加以下片段。
{% extends 'base.html' %}
{% load static %}
{% block content %}
<!-- Main Search results -->
<div id="result-container">
<div id='results'>
{% for hero in heros %}
<div class="card-container center" id="data-id">
<div class="card-img-container">
<!-- the super hero image -->
<img src="{{hero.images.sm}}"> //the super hero image
</div>
<!-- superhero name -->
<div id="details_btn" class="card-name">{{hero.name}}</div>
<div class="card-btns">
<a href="{% url 'single-hero' hero.id %}"><button class="btn primary">View</button></a>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
我们使用一个for循环来浏览从API获取的超级英雄列表。然后我们显示名字、图片和一个按钮,以进入每个超级英雄的特定页面。
单一超级英雄页面
这个页面是由def single_hero(request, id) 函数渲染的。在这个页面上,我们访问一个单一超级英雄的所有属性。
在模板文件夹中,创建一个名为single-hero.html 的新文件,然后添加下面的片段来显示超级英雄的图像。
{% extends 'base.html' %}
{% load static %}
{% block content %}
<div class="container">
<!-- A navigation bar -->
<div id="top-bar" style="color: #02a86b;">
<div><a href="#powerstats">Powerstats</a></div>
<div><a href="#appearance-target">Appearance</a></div>
<div><a href="#biography-target">Biography</a></div>
<div><a href="#occupation-target">Occupation</a></div>
<div><a href="#connections-target">Connections</a></div>
</div>
<div id='data-container'>
<!-- Image of the hero -->
<div id="image">
<img width="400" height="400" src="{{hero.images.sm}}">
</div>
<div id="detail-container">
<!-- powerstatts -->
<!-- Appearance -->
<!-- Biography -->
<!-- occupation -->
<!-- connections -->
</div>
</div>
</div>
{% endblock %}
要显示英雄的力量统计,在detail-container div中添加这块代码。
<div class="detail-item">
<!-- Powerstats bars -->
<span class="anchor" id="powerstats"></span>
<h4 id="powerstats">{{ hero.name }}'s' Powerstats</h4>
<div id="stats-container">
<table class="table table-bordered">
<thead>
<tr>
<th>Metrics</th>
<th>Measure</th>
</tr>
</thead>
<tbody>
<tr>
<td>Intelligence</td>
<td>{{hero.powerstats.intelligence}}</td>
</tr>
<tr>
<td>Strength</td>
<td>{{hero.powerstats.strength}}</td>
</tr>
<tr>
<td>Speed</td>
<td>{{hero.powerstats.speed}}</td>
</tr>
<tr>
<td>Durability</td>
<td>{{hero.powerstats.durability}}</td>
</tr>
<tr>
<td>Power</td>
<td>{{hero.powerstats.combat}}</td>
</tr>
</tbody>
</table>
</div>
</div>

要显示英雄的详细资料,我们要做的是:。
<div class="detail-item">
<span class="anchor" id="appearance-target"></span>
<h1>Appearance</h1>
<section id="appearance">
<table class="table table-bordered">
<thead>
<tr>
<th>Metrics</th>
<th>Measure</th>
</tr>
</thead>
<tbody>
<tr>
<td>Gender</td>
<td>{{hero.appearance.gender }}</td>
</tr>
<tr>
<td>Race</td>
<td>{{hero.appearance.race}}</td>
</tr>
<tr>
<td>Height</td>
<td>{{hero.appearance.height}}</td>
</tr>
<tr>
<td>Weight</td>
<td>{{hero.appearance.weight}}</td>
</tr>
</tbody>
</table>
</section>
</div>
超级英雄的传记细节。
<div class="detail-item">
<span class="anchor" id="biography-target"></span>
<h1>Biography</h1>
<section id="biography">
<table class="table table-bordered">
<thead>
<tr>
<th>Metrics</th>
<th>Measure</th>
</tr>
</thead>
<tbody>
<tr>
<td>Full Name</td>
<td>{{hero.biography.fullName }}</td>
</tr>
<tr>
<td>Alter Egos</td>
<td>{{hero.biography.alterEgos}}</td>
</tr>
<tr>
<td>Aliases</td>
<td>{{hero.biography.aliases}}</td>
</tr>
<tr>
<td>Place of Birth</td>
<td>{{hero.biography.placeOfBirth }}</td>
</tr>
<tr>
<td>First Appearance</td>
<td>{{hero.biography.firstAppearance }}</td>
</tr>
<tr>
<td>Publisher</td>
<td>{{hero.biography.publisher }}</td>
</tr>
<tr>
<td>Alignment</td>
<td>{{hero.biography.alignment }}</td>
</tr>
</tbody>
</table>
</section>
</div>
超级英雄的职业细节。
<div class="detail-item">
<span class="anchor" id="occupation-target"></span>
<h1>Occupation</h1>
<section id="occupation">
<table class="table table-bordered">
<thead>
<tr>
<th>Metrics</th>
<th>Measure</th>
</tr>
</thead>
<tbody>
<tr>
<td>Occupation</td>
<td>{{hero.work.occupation}}</td>
</tr>
<tr>
<td>Base</td>
<td>{{hero.work.base}}</td>
</tr>
</tbody>
</table>
</section>
</div>
连接细节。
<div class="detail-item">
<span class="anchor" id="connections-target"></span>
<h1>Connections</h1>
<section id="connections">
<table class="table table-bordered">
<thead>
<tr>
<th>Metrics</th>
<th>Measure</th>
</tr>
</thead>
<tbody>
<tr>
<td>Group Affiliation</td>
<td>{{hero.connections.groupAffiliation}}</td>
</tr>
<tr>
<td>Relatives</td>
<td>{{hero.connections.relatives }}</td>
</tr>
</tbody>
</table>
</section>
</div>

静态文件夹
static文件夹包含项目所需的所有静态文件。这些文件包括图片、css、javascript和其他媒体文件。
在settings.py 文件中添加以下片段,以设置静态文件夹。
#at the beginning of the file
from pathlib import Path
import environ
import os
# at the end of the file
env = environ.Env()
environ.Env.read_env()
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
最终的应用程序应该如下图所示。

结论
Superhero API是一个简单且易于使用的中间件。本教程讨论了如何使用API来构建一个超级英雄的应用程序。
首先,我们获取了数据并在用户界面上进行了渲染。本教程应该为使用超级英雄API和其他带有Django框架的API提供一个开端。