如何在 Django 中通过外部 API 填充数据库。
在今天的文章中,我将通过构建一个小型项目,讲解如何在 Django 中使用外部 API 向数据库填充数据。为此,我们将使用 MealDB API,https://www.themealdb.com/api.php并使用 Bootstrap 进行样式设计。
首先,创建一个新项目和虚拟环境。
django-admin startproject meal_project
切换到项目目录并创建一个新应用:
cd meal_project
python manage.py startapp meal_app
将新创建的应用添加到“settings.py”下的已安装应用列表中。
INSTALLED_APPS = [
'meal_app',
]
在根目录下创建一个名为“templates”的文件夹,并将其添加到“settings.py”文件中。
TEMPLATES = [
'DIRS': [os.path.join(BASE_DIR, 'templates')],
]
在 meal_app 中,创建一个 'urls.py' 文件,并在 'meal_project' urls.py 文件中,包含 meal_app 的 urls.py 文件的路径。
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('', include ('meal_app.urls'))
]
在 meal_app.urls 文件中,添加视图的路径。视图中包含列表视图和详情视图。
from django.urls import path
from product_app import views
urlpatterns = [
path('', views.get_meals, name = "get_meals"),
path('meals/<int:id>/',views.meal_detail, name = "meal_detail")
]
在模板文件夹中,创建一个名为“meals”的文件夹,并在其中创建一个名为“base.html”的文件,所有其他模板都将继承该文件。
base.html:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Movie App</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
{% block content%}
{% endblock %}
<script src = "{% static 'js/script.js' %}"></script>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" crossorigin="anonymous"></script>
</body>
</html>
然后meal.html
{% extends 'meals/base.html'%}
{% load static %}
{% block content %}
<div class = "container">
<br>
<h2 class = "text-center">Search for your favorite Meals</h2>
<br>
<form method="GET">
<input type = "text" name = "name" placeholder="Search..." class = "text-center">
<button type = "submit" class = "btn-danger btn-sm">SEARCH MEAL</button>
</form>
</div>
{% endblock %}
它meal.html包含一个简单的搜索表单和一个提交按钮。
接下来,我们需要创建一个模型,并用来自餐食数据库 API 的数据填充该模型。模型中的字段对应于 API 中我们希望填充到数据库中的特定属性。
models.py
from django.db import models
class Meal(models.Model):
name = models.CharField(max_length=50, blank = True, null = True)
category = models.CharField(max_length=10, blank = True, null = True)
instructions = models.CharField(max_length=4000, blank = True, null = True)
region = models.CharField(max_length=20, blank = True, null = True)
slug = models.SlugField(default = 'test')
image_url = models.CharField( max_length=50, blank = True, null = True)
def __str__(self):
return self.name
我们的 API 界面如下所示:
现在是时候迁移我们的数据库并创建数据库表了。
python manage.py makemigrations
python manage.py migrate
接下来,我们需要安装一个用于发出HTTP请求的Python库;
pip install requests
项目的主要逻辑将位于views.py.
from django.shortcuts import render
from meal_app.models import Meal
import requests
def get_meals(request):
all_meals = {}
if 'name' in request.GET:
name = request.GET['name']
url =
'https://www.themealdb.com/api/json/v1/1/search.php?
s=%s' % name
response = requests.get(url)
data = response.json()
meals = data['meals']
for i in meals:
meal_data = Meal(
name = i['strMeal'],
category = i['strCategory'],
instructions = i['strInstructions'],
region = i['strArea'],
slug = i['idMeal'],
image_url = i['strMealThumb']
)
meal_data.save()
all_meals = Meal.objects.all().order_by('-id')
return render (request, 'meals/meal.html', { "all_meals":
all_meals} )
在上述函数中get_meals,我们使用 `getSearch()` 方法获取用户在搜索框中输入的值request.GET,并将其赋值给一个变量name。然后,我们在发出 HTTP 请求时,将此变量作为搜索词传递到 URL 中。我们收到响应并将其转换为 JSON 格式。这将返回一个列表,我们将其保存到该变量中meals。
name = request.GET['name']
url = 'https://www.themealdb.com/api/json/v1/1/search.php?s=%s' % name
response = requests.get(url)
data = response.json()
meals = data['meals']
现在,为了将 HTTP 请求返回的列表填充到我们的数据库中,我们需要遍历列表项并将参数作为字段分配到我们的模型中。
for i in meals:
meal_data = Meal(
name = i['strMeal'],
category = i['strCategory'],
instructions = i['strInstructions'],
region = i['strArea'],
slug = i['idMeal'],
image_url = i['strMealThumb']
)
然后我们将其保存到数据库中,并将其作为上下文传递给我们的模板:
from django.shortcuts import render
from meal_app.models import Meal
import requests
def get_meals(request):
all_meals = {}
if 'name' in request.GET:
name = request.GET['name']
url =
'https://www.themealdb.com/api/json/v1/1/search.php?
s=%s' % name
response = requests.get(url)
data = response.json()
meals = data['meals']
for i in meals:
meal_data = Meal(
name = i['strMeal'],
category = i['strCategory'],
instructions = i['strInstructions'],
region = i['strArea'],
slug = i['idMeal'],
image_url = i['strMealThumb']
)
meal_data.save()
all_meals = Meal.objects.all().order_by('-id')
return render (request, 'meals/meal.html', { "all_meals":
all_meals} )
之内meal,html
{% extends 'meals/base.html'%}
{% load static %}
{% block content %}
<div class = "container">
<div class = "text-center container">
<br>
<h2 class = "text-center">Search for your favorite Meals</h2>
<br>
<form method="GET">
<input type = "text" name = "name" placeholder="Search..." class = "text-center">
<button type = "submit" class = "btn-danger btn-sm">SEARCH MEAL</button>
</form>
</div>
<br><br>
<div class="row">
{% for meal in all_meals %}
<div class="col-md-4 col-sm-6 col-lg-3">
<div class="card">
<img class="card-img-top" src="{{ meal.image_url }}" alt="Card image cap">
<div class="card-body text-center">
<p class="card-title">{{ meal.name }}</p>
<hr>
<p class="card-text">{{ meal.region }}</p>
<a href="/meals/{{meal.id}}"
><input
type="submit"
value="Learn More"
class="btn btn-danger btn-sm"
type="button"
/></a>
</div>
</div>
<br><br><br>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
现在,如果用户搜索某种餐点,它会在页面上显示,并自动保存到数据库中。
MEAL LIST PAGE:
DATABASE:
最后,我们创建一个餐食详情页面:
meal_detail.html
{% extends 'meals/base.html'%}
{% load static %}
{% block content %}
<div class = "container">
<br><br>
<div class="row">
<div class="col-md-5">
<br>
<img class="img-fluid" src="{{ meal.image_url }}" alt="" style = "width: 90%;">
<br><br>
<h3 class="card-title text-center ">{{ meal.name }}</h3>
</div>
<div class="col-md-7 shadow-lg p-3 mb-5 bg-white rounded">
<h1 class="my-3">Food Description</h1>
<p class = "lead">{{ meal.instructions }}</p>
<h1 class="my-3">Food Details</h1>
<ul>
<li>{{ meal.category }}</li>
<li>{{ meal.region }}</li>
</ul>
</div>
</div>
</div>
{% endblock %}
在views.py
def meal_detail(request, id):
meal = Meal.objects.get(id = id)
print(meal)
return render (
request,
'meals/meal_detail.html',
{'meal': meal}
)
现在,当我们点击Learn More按钮时,就会进入meal_details.html模板页面。
谢谢!☺️
文章来源:https://dev.to/yahaya_hk/how-to-populate-your-database-with-data-from-an-external-api-in-django-398i




