发布于 2026-01-06 0 阅读
0

如何在 Django 中通过外部 API 填充数据库。

如何在 Django 中通过外部 API 填充数据库。

在今天的文章中,我将通过构建一个小型项目,讲解如何在 Django 中使用外部 API 向数据库填充数据。为此,我们将使用 MealDB API,https://www.themealdb.com/api.php并使用 Bootstrap 进行样式设计。

首先,创建一个新项目和虚拟环境。

django-admin startproject meal_project
Enter fullscreen mode Exit fullscreen mode

切换到项目目录并创建一个新应用:

cd meal_project
python manage.py startapp meal_app

Enter fullscreen mode Exit fullscreen mode

将新创建的应用添加到“settings.py”下的已安装应用列表中。

INSTALLED_APPS = [
'meal_app',
]
Enter fullscreen mode Exit fullscreen mode

在根目录下创建一个名为“templates”的文件夹,并将其添加到“settings.py”文件中。

TEMPLATES = [
 'DIRS': [os.path.join(BASE_DIR, 'templates')],
]
Enter fullscreen mode Exit fullscreen mode

在 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'))
]
Enter fullscreen mode Exit fullscreen mode

在 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")
]
Enter fullscreen mode Exit fullscreen mode

在模板文件夹中,创建一个名为“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>
Enter fullscreen mode Exit fullscreen mode

然后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 %}

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

我们的 API 界面如下所示:

替代文字

现在是时候迁移我们的数据库并创建数据库表了。

python manage.py makemigrations
python manage.py migrate
Enter fullscreen mode Exit fullscreen mode

接下来,我们需要安装一个用于发出HTTP请求的Python库;

pip install requests
Enter fullscreen mode Exit fullscreen mode

项目的主要逻辑将位于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} )

Enter fullscreen mode Exit fullscreen mode

在上述函数中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']
Enter fullscreen mode Exit fullscreen mode

现在,为了将 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']
            )

Enter fullscreen mode Exit fullscreen mode

然后我们将其保存到数据库中,并将其作为上下文传递给我们的模板:

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} )

Enter fullscreen mode Exit fullscreen mode

之内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 %}

Enter fullscreen mode Exit fullscreen mode

现在,如果用户搜索某种餐点,它会在页面上显示,并自动保存到数据库中。

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 %}
Enter fullscreen mode Exit fullscreen mode

views.py

def meal_detail(request, id):
    meal = Meal.objects.get(id = id)
    print(meal)
    return render (
        request,
        'meals/meal_detail.html',
        {'meal': meal}
    )

Enter fullscreen mode Exit fullscreen mode

现在,当我们点击Learn More按钮时,就会进入meal_details.html模板页面。

替代文字

谢谢!☺️

文章来源:https://dev.to/yahaya_hk/how-to-populate-your-database-with-data-from-an-external-api-in-django-398i