django中的app_如何在Django中构建Weather App

news/2024/7/6 0:55:41

django中的app

介绍 (Introduction)

In this article we’ll build a simple Django app that displays the current weather for various cities. To get the current weather data, we’ll use the Open Weather Map API.

在本文中,我们将构建一个简单的Django应用,该应用显示各个城市的当前天气。 要获取当前的天气数据,我们将使用Open Weather Map API 。

We’ll work with a database and create a form, so the concepts used here are applicable to more complicated projects.

我们将使用数据库并创建表单,因此此处使用的概念适用于更复杂的项目。

The code in this article was written with Python 3 and Django 2.0, so to follow this tutorial, you should be somewhat familiar with both.

本文中的代码是使用Python 3和Django 2.0编写的,因此,要熟悉本教程,您应该对两者都有些熟悉。

Here’s what our app is going to look like when we’re done.

完成后,这就是我们的应用程序的外观。

All the code for this article is on GitHub.

本文的所有代码都在GitHub上 。

安装 (Installation)

Installing Django is like installing any other Python library: you can start a virtual environment and run pip to install Django, or you can do what I do and create a project directory, run pipenv, and then activate the pipenv shell. Either method works, but for this article I’ll be using pipenv.

安装Django就像安装其他Python库一样:您可以启动虚拟环境并运行pip来安装Django,或者可以执行我的操作并创建项目目录,运行pipenv ,然后激活pipenv shell。 两种方法都可以,但是对于本文,我将使用pipenv

  • pipenv install django

    pipenv安装django

This will install the latest version of Django for you. At the time of writing this article, Django is on version 2.0.4.

这将为您安装最新版本的Django。 在撰写本文时,Django的版本为2.0.4。

Once you have Django installed, create and navigate to a directory for this project if you haven’t already. Once there, you can run the startproject command that Django gives you to generate the project.

安装Django之后,请创建并导航至该项目的目录(如果尚未安装)。 startproject那里后,您可以运行Django提供的startproject命令来生成项目。

  • django-admin startproject the_weather

    django-admin startproject the_weather

Django should have created a few new files in your directory.

Django应该在您的目录中创建了一些新文件。

Let’s try starting up our development server. To do that, navigate to the new directory and use manage.py to run the runserver command in your terminal:

让我们尝试启动我们的开发服务器。 为此,请导航到新目录并使用manage.py在终端中运行runserver命令:

  • cd the_weather

    cd the_weather
  • python manage.py runserver

    python manage.py运行服务器

If you look at your terminal, you should see the URL for your app. By default it should be 127.0.0.1:8000.

如果您查看终端,应该会看到应用程序的URL。 默认情况下应该是127.0.0.1:8000

Open up your browser and go to that URL.

打开浏览器,然后转到该URL。

If you see that, you know you’ve set up Django correctly. You definitely should see it because we haven’t even tried modifying the code yet.

如果看到该信息,说明您已正确设置了Django。 您肯定应该看到它,因为我们还没有尝试修改代码。

管理员控制台 (The Admin Dashboard)

Next we want to take a look at the admin dashboard Django gives us. To do that, first we have to migrate our database, which means Django will create the pre-defined tables that are needed for the default apps. To do this, run the migrate command. Stop the server by using CTRL+C and then run:

接下来,我们要看看Django给我们的管理仪表板。 为此,首先我们必须迁移数据库,这意味着Django将创建默认应用所需的预定义表。 为此,请运行migrate命令。 通过使用CTRL+C停止服务器,然后运行:

  • python manage.py migrate

    python manage.py迁移

By running that command, Django has created a SQLite database for you, the default database in the settings, and it has added several tables to that database. You’ll know if the database was created if you see a new db.sqlite3 file in your project directory.

通过运行该命令,Django为您创建了SQLite数据库,这是设置中的默认数据库,并且已向该数据库添加了多个表。 你要知道,如果你看到一个新的数据库创建了数据库。 项目目录中的sqlite3文件。

One of the tables Django gives us is a user table, which will be used to store any users in our app. The app we’re building doesn’t need any users, but having an admin user will allow us to access the admin dashboard.

Django提供给我们的表之一是用户表,该表将用于存储应用程序中的所有用户。 我们正在构建的应用不需要任何用户,但是拥有管理员用户将使我们能够访问管理仪表板。

To create an admin user, we’ll run the createsuperuser command.

要创建管理员用户,我们将运行createsuperuser命令。

  • python manage.py createsuperuser

    python manage.py createsuperuser

Follow the instructions by giving a username, email address, and a password for your admin user. Once you’ve done that, you’ll need to start the server again and navigate to the admin dashboard.

按照说明进行操作,并为您的管理员用户提供用户名,电子邮件地址和密码。 完成此操作后,您需要再次启动服务器并导航到管理仪表板。

  • python manage.py runserver

    python manage.py运行服务器

Then go to 127.0.0.1:8000/admin.

然后转到127.0.0.1:8000/admin

The reason why we can go to this page is because because admin is set up in our urls.py (the reason why we can see the congratulations page is because Django gives you that until you add your own URLs).

之所以可以转到此页面,是因为在urls.py设置了admin(之所以可以看到祝贺页面,是因为Django为您提供了这一功能,直到您添加自己的URL为止)。

If you log in with the username and password you just created, you should see the Django Admin Dashboard.

如果使用刚创建的用户名和密码登录,则应该看到Django Admin Dashboard。

Groups and users represent two models Django gives us access to. Models are just code representations of tables in a database. Even though Django created more tables, there’s no need to access the rest of them directly, so no models were created.

组和用户代表Django允许我们访问的两个模型。 模型只是数据库中表的代码表示。 即使Django创建了更多表,也无需直接访问其余表,因此不会创建任何模型。

If you click on 'user' you should see more detail about the user table, and you should see the user you created. It’s a good idea to explore by clicking different links in the dashboard to see what’s there. Just be careful not to delete your user, otherwise you’ll have to run createsuperuser again.

如果单击'user' ,则应该看到有关用户表的更多详细信息,并且还应该看到创建的用户。 单击仪表板中的其他链接以查看其中的内容是一个好主意。 请注意不要删除用户,否则,您将不得不再次运行createsuperuser

Let’s leave the admin dashboard for now and go to the code. We need to create an app inside of our project for our weather app.

现在让我们离开管理仪表板,转到代码。 我们需要在项目内部为天气应用程序创建一个应用程序。

创建应用 (Creating the App)

In Django, you can separate functionality in your project by using apps. I think app is a confusing name because we usually refer to an app as being the entire project, but in the case of Django, app refers to a specific piece of functionality in your project. For example, if you look at the settings.py file, you’ll see the INSTALLED_APPS list.

在Django中,您可以使用应用来分离项目中的功能。 我认为应用程序是一个令人困惑的名称,因为我们通常将应用程序称为整个项目,但就Django而言,应用程序指的是项目中的特定功能。 例如,如果查看settings.py文件,则会看到INSTALLED_APPS列表。

The first of the installed apps, django.contrib.admin is what we just used. It handles all the admin functionality and nothing else. Another app in our project by default are things like auth, which allowed us to log into our admin dashboard.

我们刚刚使用的是已安装的第一个应用程序django.contrib.admin。 它处理所有管理功能,仅此而已。 默认情况下,项目中的另一个应用程序是auth之类的东西,它使我们能够登录到管理仪表板。

In our case, we need to create a new app to handle everything related to showing the weather. To create that app, stop the server with CTRL+C and run:

在我们的案例中,我们需要创建一个新应用来处理与显示天气有关的所有事情。 要创建该应用,请使用CTRL+C停止服务器并运行:

  • python manage.py startapp weather

    python manage.py startapp天气

By running startapp, Django has added a new directory and more files to our project.

通过运行startapp ,Django为我们的项目添加了一个新目录和更多文件。

With the latest files generated, let’s create a new file called urls.py in our app directory.

生成最新文件后,让我们在应用程序目录中创建一个名为urls.py的新文件。

urls.py
urls.py
from django.urls import path

urlpatterns = [
]

This file is similar to the urls.py in our the_weather directory. The difference is that this urls.py file contains all the URLs that are relevant to the app itself.

该文件类似于urls.py我们the_weather目录。 不同之处在于此urls.py文件包含与应用程序本身相关的所有URL。

We’re not specifying a URL yet, but we can set up the project to recognize our app and route any URLs specific to our app to the app urls.py file.

我们尚未指定URL,但是我们可以设置项目以识别我们的应用程序并将特定于我们应用程序的所有URL路由到应用程序urls.py文件。

First, go to the INSTALLED_APPS list and add this app to the list.

首先,转到INSTALLED_APPS列表,然后将此应用添加到列表中。

the_weather/the_weather/settings.py
the_weather / the_weather / settings.py
...

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'weather',
]

...

This lets Django know we want to use the weather app in our project. By doing this, Django will know where to look for migrations and the URLs.

这使Django知道我们要在项目中使用weather应用程序。 这样,Django将知道在何处查找迁移和URL。

Next, we need to modify the original urls.py to point to our app urls.py file. To do that, we add a line under the existing path for the admin dashboard. We also need to import include so we can point to our app urls.py file.

接下来,我们需要修改原始的urls.py以指向我们的应用程序urls.py文件。 为此,我们在管理控制台的现有路径下添加一行。 我们还需要导入include以便可以指向我们的应用程序urls.py文件。

the_weather/the_weather/urls.py
the_weather / the_weather / urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('weather.urls')),
]

The empty string means that we won’t use an endpoint for the entry point to our app. Instead we’ll let the app handle any specific endpoints. We could have put something like path (‘weather/’, …), which would have meant we would have to type 127.0.0.1:8000/weather/ to get anything associated with our weather app. But since our project is simple, we won’t be doing that here.

空字符串表示我们不会将端点用作应用程序的入口点。 相反,我们将让该应用处理任何特定的端点。 我们本可以放置类似path('weather /',…)之类的东西,这意味着我们必须输入127.0.0.1:8000/weather/才能获得与我们的天气应用程序相关的任何内容。 但是由于我们的项目很简单,因此我们在这里不会这样做。

添加模板和视图 (Adding the Template and View)

Now for the first interesting thing we’re going to do. We need to add the template to our project.

现在,我们要做的第一件事是有趣的。 我们需要将模板添加到我们的项目中。

A template in Django is just an HTML file that allows for extra syntax that makes the template dynamic. We’ll be able to do things like add variables, if statements, and loops, among other things.

Django中的模板只是一个HTML文件,它允许使模板动态化的额外语法。 我们将能够做诸如添加变量, if语句和循环之类的事情。

We have an HTML file, but this will be enough for us to start.

我们有一个HTML文件,但这足以让我们开始。

We’re going to create a template directory to put this file in.

我们将创建一个模板目录来放置该文件。

  • cd weather

    cd天气
  • mkdir templates && cd templates

    mkdir模板&& cd模板
  • mkdir weather

    麦克迪尔天气

We also created another directory with the same name as our app. We did this because Django combines all the template directories from the various apps we have. To prevent filenames being duplicated, we can use the name of our app to prevent the duplicates.

我们还创建了另一个名称与应用程序相同的目录。 我们之所以这样做,是因为Django结合了我们拥有的各种应用程序中的所有模板目录。 为了防止文件名重复,我们可以使用应用程序的名称来防止重复。

Inside of the weather directory, create a new file called index.html. This will be our main template. Here’s the HTML we’ll use for the template:

在weather目录中,创建一个名为index.html的新文件。 这将是我们的主要模板。 这是我们将用于模板HTML:

the_weather/weather/templates/weather/index.html
the_weather / weather / templates / weather / index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>What's the weather like?</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.2/css/bulma.css" />
</head>
<body>
    <section class="hero is-primary">
        <div class="hero-body">
            <div class="container">
                <h1 class="title">
                    What's the weather like?
                </h1>
            </div>
        </div>
    </section>
    <section class="section">
        <div class="container">
            <div class="columns">
                <div class="column is-offset-4 is-4">
                    <form method="POST">
                        <div class="field has-addons">
                            <div class="control is-expanded">
                                <input class="input" type="text" placeholder="City Name">
                            </div>
                            <div class="control">
                                <button class="button is-info">
                                    Add City
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </section>
    <section class="section">
        <div class="container">
            <div class="columns">
                <div class="column is-offset-4 is-4">
                    <div class="box">
                        <article class="media">
                            <div class="media-left">
                                <figure class="image is-50x50">
                                    <img src="http://openweathermap.org/img/w/10d.png" alt="Image">
                                </figure>
                            </div>
                            <div class="media-content">
                                <div class="content">
                                    <p>
                                        <span class="title">Las Vegas</span>
                                        <br>
                                        <span class="subtitle">29° F</span>
                                        <br> thunderstorm with heavy rain
                                    </p>
                                </div>
                            </div>
                        </article>
                    </div>
                </div>
            </div>
        </div>
    </section>
    <footer class="footer">
    </footer>
</body>
</html>

Now that we have our template created, let’s create a view and URL combination so we can actually see this in our app.

现在我们已经创建了模板,让我们创建一个视图和URL组合,以便我们实际上可以在我们的应用程序中看到它。

Views in Django are either functions or classes. In our case since we’re creating a simple view, we’ll create a function. Add this function to your views.py:

Django中的视图是函数或类。 就我们而言,由于我们正在创建一个简单的视图,因此我们将创建一个函数。 将此功能添加到您的views.py

the_weather/weather/views.py
the_weather / weather / views.py
from django.shortcuts import render

def index(request):
    return render(request, 'weather/index.html') #returns the index.html template

We’re naming our view index because it will be at the index of our app, which is the root URL. To have the template render, we return request, which is necessary for the render function, and the name of the template file we want to render, in this case weather/index.html.

我们正在命名视图index因为它将位于我们应用程序的索引(即根URL)处。 要渲染模板,我们返回请求(这是render函数所必需的)以及我们要渲染的模板文件的名称,在本例中为weather/index.html

Let’s add the URL that will send the request to this view. In the urls.py for the app, update the urlpatterns list.

让我们添加将请求发送到该视图的URL。 在网址中py作为应用程序,请更新urlpatterns列表。

the_weather/weather/urls.py
the_weather / weather / urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index),  #the path for our index view
]

This allows us to reference the view we just created.

这使我们可以引用刚刚创建的视图。

Django is going to match any URL without an endpoint and route it to the view function we created.

Django将匹配没有端点的任何URL,并将其路由到我们创建的view函数。

Go back to your project root, start the server, and go to 127.0.0.1:8000 again.

返回项目根目录,启动服务器,然后再次转到127.0.0.1:8000

  • python manage.py runserver

    python manage.py运行服务器

What we see now is just the result of the HTML you have in index.html file. You’ll see an input to add a city and the weather for Las Vegas. However, the form doesn’t work and the weather is just a placeholder, but don’t worry, because we’ll be creating those for this app.

我们现在看到的只是index.html文件中HTML的结果。 您会看到一个输入,用于添加拉斯维加斯的城市和天气。 但是,该表单不起作用,天气只是一个占位符,但请不要担心,因为我们将为此应用程序创建这些占位符。

使用天气API (Using the Weather API)

What we want to do now is sign up for the Open Weather Map API. This will allow us to get real-time weather for any cities that we add in our app.

我们现在要做的是注册Open Weather Map API 。 这将使我们能够获取应用程序中添加的任何城市的实时天气。

Go to the site, create an account and then go to the API keys on their dashboard. Enter a name and generate a new API key. This key will allow us to use the API to get the weather.

转到该站点,创建一个帐户,然后转到其仪表板上的API密钥。 输入名称并生成新的API密钥。 此密钥将使我们能够使用API​​来获取天气。

The one endpoint we’ll use is below, so you can see the data that gets returned by modifying the following URL with your API key and navigating to the URL in your browser. It may take a few minutes for your API key to become active, so if it doesn’t work at first, try again in after a few minutes.

我们将使用的一个端点在下面,因此您可以通过使用API​​密钥修改以下URL并导航至浏览器中的URL来查看返回的数据。 您的API密钥可能需要几分钟的时间才能激活,因此,如果一开始不起作用,请在几分钟后重试。

http://api.openweathermap.org/data/2.5/weather?q=las%20vegas&units=imperial&appid=YOUR_APP_KEY

With that, let’s add in a request to get the data into our app.

这样,让我们​​添加一个请求以将数据导入我们的应用程序。

First, we’ll need to install requests so we can call the API from inside our app.

首先,我们需要安装请求,以便我们可以从应用程序内部调用API。

  • pipenv install requests

    pipenv安装请求

Let’s update our index view to send a request to the URL we have.

让我们更新索引视图,以将请求发送到我们拥有的URL。

the_weather/weather/views.py
the_weather / weather / views.py
from django.shortcuts import render
import requests

def index(request):
    url = 'http://api.openweathermap.org/data/2.5/weather?q={}&units=imperial&appid=YOUR_APP_KEY'
    city = 'Las Vegas'
    city_weather = requests.get(url.format(city)).json() #request the API data and convert the JSON to Python data types

    return render(request, 'weather/index.html') #returns the index.html template

With those three lines, we’re adding the URL that we will send a request to. We’ll make the part for the city a placeholder for when we allow users to add their own cities.

在这三行中,我们添加了向其发送请求的URL。 当我们允许用户添加自己的城市时,我们将为城市提供占位符。

For now we’ll set the city to be Las Vegas, but later this will be set to the cities from the database.

现在,我们将城市设置为拉斯维加斯,但稍后将其从数据库中设置为城市。

Finally, we’ll send the request to the URL using the city and get the JSON representation of that city. If we print that to the console we can see the same data we saw when we put the URL in our address bar.

最后,我们将使用城市将请求发送到URL,并获取该城市的JSON表示形式。 如果将其打印到控制台,则可以看到与将URL放入地址栏中时看到的相同数据。

If you start your server again and reload the page, you’ll see the data get printed to your console.

如果再次启动服务器并重新加载页面,则会看到数据已打印到控制台。

在模板中显示数据 (Displaying the Data in the Template)

Next, we need to pass the data to the template so it can be displayed to the user.

接下来,我们需要将数据传递到模板,以便可以将其显示给用户。

Let’s create a dictionary to hold all of the data we need. Of the data returned to us, we need temp, description, and icon.

让我们创建一个字典来保存我们需要的所有数据。 在返回给我们的数据中,我们需要临时文件,说明和图标。

the_weather/weather/views.py
the_weather / weather / views.py
def index(request):
    ...
    weather = {
        'city' : city,
        'temperature' : city_weather['main']['temp'],
        'description' : city_weather['weather'][0]['description'],
        'icon' : city_weather['weather'][0]['icon']
    }

    return render(request, 'weather/index.html') #returns the index.html template

Now that we have all the information we want, we can pass that to the template. To pass it to the template, we’ll create a variable called context. This will be a dictionary that allows us to use its values inside of the template.

现在我们有了所需的所有信息,我们可以将其传递给模板。 要将其传递给模板,我们将创建一个名为context的变量。 这将是一个字典,允许我们在模板内部使用其值。

the_weather/weather/views.py
the_weather / weather / views.py
def index(request):
    ...
    context = {'weather' : weather}
    return render(request, 'weather/index.html', context) #returns the index.html template

And then in render, we’ll add the context as the third argument.

然后在渲染中,我们将上下文添加为第三个参数。

With the weather data added inside of context, let’s go to the template to add the data.

将天气数据添加到上下文中后,让我们转到模板以添加数据。

Inside of the template, all we need to do is modify the HTML to use variables instead of the values I typed in. Variables will use {{ }} tags, and they will reference anything inside of your context dictionary.

在模板内部,我们要做的就是修改HTML以使用变量而不是我键入的值。变量将使用{{}}标签,并且它们将引用上下文词典中的所有内容。

Note that Django converts dictionary keys so you can only access them using dot notation. For example, weather.city will give us the city name. We don’t use weather['city'] like we would in Python.

请注意,Django会转换字典键,因此您只能使用点表示法来访问它们。 例如, weather.city将为我们提供城市名称。 我们不像在Python中那样使用weather['city']

Find the box div, and update it to this:

找到div框,并将其更新为:

the_weather/weather/templates/weather/index.html
the_weather / weather / templates / weather / index.html
<div class="box">
    <article class="media">
        <div class="media-left">
            <figure class="image is-50x50">
                <img src="http://openweathermap.org/img/w/{{ weather.icon }}.png" alt="Image">
            </figure>
        </div>
        <div class="media-content">
            <div class="content">
                <p>
                    <span class="title">{{ weather.city }}</span>
                    <br>
                    <span class="subtitle">{{ weather.temperature }}° F</span>
                    <br> {{ weather.description }}
                </p>
            </div>
        </div>
    </article>
</div>

With all the variables replaced, we should now see the current weather for our city.

替换所有变量后,我们现在应该可以看到城市的当前天气。

Now we can see the weather for one city, but we had to hard code the city. What we want to do now is pull from the database and show the cities that are in our database.

现在我们可以看到一个城市的天气,但是我们必须对该城市进行硬编码。 我们现在要做的是从数据库中提取并显示数据库中的城市。

To do that, we’ll create a table in our database to hold the cities that we want to know the weather for. We’ll create a model for this.

为此,我们将在数据库中创建一个表,以保存我们想知道天气的城市。 我们将为此创建一个模型。

Go to the models.py file in your weather app, and add the following:

转到您的天气应用程序中的models.py文件,并添加以下内容:

the_weather/weather/models.py
the_weather / weather / models.py
from django.db import models

class City(models.Model):
    name = models.CharField(max_length=25)

    def _str_(self): #show the actual city name on the dashboard
        return self.name

    class Meta: #show the plural of city as cities instead of citys
        verbose_name_plural = 'cities'

This will create a table in our database that will have a column called name, which is the name of the city. This city will be a charfield, which is just a string.

这将在我们的数据库中创建一个表,该表具有名为name的列,这是城市的名称。 这个城市将是一个charfield ,只是一个字符串。

To get these changes in the database, we have to run makemigrations to generate the code to update the database and migrate to apply those changes. Let’s do that now:

为了在数据库中获得这些更改,我们必须运行makemigrations来生成代码以更新数据库并进行迁移以应用这些更改。 现在开始:

  • python manage.py makemigrations

    python manage.py makemigrations
  • python manage.py migrate

    python manage.py迁移

We need to make it to where we can see this model on our admin dashboard. To do that, we need to register it in our admin.py file.

我们需要使其在管理仪表板上可以看到该模型的地方。 为此,我们需要在admin.py文件中注册它。

the_weather/weather/admin.py
the_weather / weather / admin.py
from django.contrib import admin
from .models import City

admin.site.register(City)

You’ll see the city as an option on the admin dashboard.

您会在管理控制台上看到城市作为选项。

We can then go into the admin dashboard and add some cities. I’ll start with three: London, Tokyo, and Las Vegas.

然后,我们可以进入管理控制台并添加一些城市。 我将从三个方面开始:伦敦,东京和拉斯维加斯。

With the entries in the database, we need to query these entries in our view. Start by importing the City model and then querying that model for all objects.

使用数据库中的条目,我们需要在视图中查询这些条目。 首先导入City模型,然后在该模型中查询所有对象。

the_weather/weather/views.py
the_weather / weather / views.py
from django.shortcuts import render
import requests
from .models import City
the_weather/weather/views.py
...
def index(request):
    url = 'http://api.openweathermap.org/data/2.5/weather?q={}&units=imperial&appid=YOUR_APP_KEY'
    cities = City.objects.all() #return all the cities in the database
    ...

Since we have the list of cities, we want to loop over them and get the weather for each one and add it to a list that will eventually be passed to the template.

由于我们具有城市列表,因此我们想遍历城市并获取每个城市的天气,并将其添加到最终将传递给模板的列表中。

This will just be a variation of what we did in the first case. The other difference is we are looping and appending each dictionary to a list. We’ll remove the original city variable in favor of a city variable in the loop:

这只是我们在第一种情况下所做的变体。 另一个区别是我们正在循环并将每个字典追加到列表中。 我们将删除原始的city变量,以在循环中使用city变量:

the_weather/weather/views.py
the_weather / weather / views.py
def index(request):
    ...
    weather_data = []

    for city in cities:

        city_weather = requests.get(url.format(city)).json() #request the API data and convert the JSON to Python data types

        weather = {
            'city' : city,
            'temperature' : city_weather['main']['temp'],
            'description' : city_weather['weather'][0]['description'],
            'icon' : city_weather['weather'][0]['icon']
        }

        weather_data.append(weather) #add the data for the current city into our list

    context = {'weather_data' : weather_data}
    ...

Now let’s update the context to pass this list instead of a single dictionary.

现在,让我们更新上下文以传递此列表,而不是单个字典。

the_weather/weather/views.py
the_weather / weather / views.py
...
    context = {'weather_data' : weather_data}
    ...

Next, inside of the template, we need to loop over this list and generate the HTML for each city in the list. To do this, we can put a for loop around the HTML that generates a single box for the city.

接下来,在模板内部,我们需要遍历此列表并为列表中的每个城市生成HTML。 为此,我们可以在HTML周围放置一个for循环,为城市生成单个框。

the_weather/weather/index.html
the_weather / weather / index.html
<div class="column is-offset-4 is-4">
    {% for weather in weather_data %}
    <div class="box">
        <article class="media">
            <div class="media-left">
                <figure class="image is-50x50">
                    <img src="http://openweathermap.org/img/w/{{ weather.icon }}.png" alt="Image">
                </figure>
            </div>
            <div class="media-content">
                <div class="content">
                    <p>
                        <span class="title">{{ weather.city }}</span>
                        <br>
                        <span class="subtitle">{{ weather.temperature }}° F</span>
                        <br> {{ weather.description }}
                    </p>
                </div>
            </div>
        </article>
    </div>
    {% endfor %}
</div>

Now we can see the data for all the cities we have in the database.

现在,我们可以查看数据库中所有城市的数据。

创建表格 (Creating the Form)

The last thing we want to do is allow the user to add a city directly in the form.

我们要做的最后一件事是允许用户直接在表单中添加城市。

To do that, we need to create a form. We could create the form directly, but since our form will have exactly the same field as our model, we can use a ModelForm.

为此,我们需要创建一个表单。 我们可以直接创建表单,但是由于表单将具有与模型完全相同的字段,因此可以使用ModelForm

Create a new file called forms.py.

创建一个名为forms.py的新文件。

the_weather/weather/forms.py
the_weather / weather / forms.py
from django.forms import ModelForm, TextInput
from .models import City

class CityForm(ModelForm):
    class Meta:
        model = City
        fields = ['name']
        widgets = {
            'name': TextInput(attrs={'class' : 'input', 'placeholder' : 'City Name'}),
        } #updates the input class to have the correct Bulma class and placeholder

To view the form, we need to create it in our view and pass it to the template.

要查看表单,我们需要在视图中创建表单并将其传递给模板。

To do that, let’s update the index video to create the form. We’ll replace the old city variable at the same time since we no longer need it. We also need to update the context so the form gets passed to the template.

为此,让我们更新索引视频以创建表单。 由于我们不再需要旧变量,因此我们将同时替换它。 我们还需要更新上下文,以便将表单传递给模板。

the_weather/weather/views.py
the_weather / weather / views.py
def index(request):
    ...
    form = CityForm()

    weather_data = []
    ...
    context = {'weather_data' : weather_data, 'form' : form}

Now in the template, let’s update the form section to use the form from our view and a csrf_token, which is necessary for POST requests in Django.

现在,在模板中,让我们更新表单部分以使用视图中的表单和csrf_token ,这对于Django中的POST请求是必需的。

<form method="POST">
    {% csrf_token %}
    <div class="field has-addons">
        <div class="control is-expanded">
            {{ form.name }}
        </div>
        <div class="control">
            <button class="button is-info">
                Add City
            </button>
        </div>
    </div>
</form>

With the form in our HTML working, we now need to handle the form data as it comes in. For that, we’ll create an if block checking for a POST request. We need to add the check for the type of request before we start grabbing the weather data so we immediately get the data for the city we add.

HTML中的表单正常工作后,我们现在需要处理表单数据的传入。为此,我们将为POST请求创建if块检查。 在开始获取天气数据之前,我们需要添加请求类型的检查,以便我们立即获取所添加城市的数据。

the_weather/weather/views.py
the_weather / weather / views.py
def index(request):
    cities = City.objects.all() #return all the cities in the database

    url = 'http://api.openweathermap.org/data/2.5/weather?q={}&units=imperial&appid=YOUR_APP_KEY'

    if request.method == 'POST': # only true if form is submitted
        form = CityForm(request.POST) # add actual request data to form for processing
        form.save() # will validate and save if validate

    form = CityForm()
    ...

By passing request.POST, we’ll be able to validate the form data.

通过传递request.POST ,我们将能够验证表单数据。

Now you should be able to type in the name of a city, click add, and see it show up. I’ll add Miami as the next city.

现在,您应该能够输入城市名称,单击添加,然后看到它出现。 我将迈阿密作为下一个城市。

When we drop out of the if block, the form will be recreated so we can add another city if we choose. The rest of the code will behave in the same way.

当我们退出if块时,将重新创建该表单,以便我们选择添加另一个城市。 其余代码将以相同的方式运行。

结论 (Conclusion)

We now have a way to keep track of the weather for multiple cities in our app.

现在,我们可以在应用程序中跟踪多个城市的天气。

In this article, we had to work with various parts of Django to get this working: views, models, forms, and templates. We also had to use the Python library requests to get the actual weather data. So even though the app is simple, you’ll use many of the same concepts in apps with more complexity.

在本文中,我们必须使用Django的各个部分才能工作:视图,模型,表单和模板。 我们还必须使用Python库请求来获取实际的天气数据。 因此,即使该应用程序很简单,您仍将在应用程序中使用许多相同的概念,但更为复杂。

翻译自: https://www.digitalocean.com/community/tutorials/how-to-build-a-weather-app-in-django

django中的app


http://www.niftyadmin.cn/n/3649122.html

相关文章

酷炫轮播广告

一、广告轮播条的简介 广告轮播条在HTML网页设计以及APP界面设计中非常常见&#xff0c;如下图所示。在Android中&#xff0c;实现的方式可以是自定义ViewPager来实现&#xff0c;但是我们程序员中流传的一句名言&#xff0c;“不要重复造轮子”。因此我们也可以通过网上已经有…

android View 详解

一、View 的概述 android.View.View(即View)类是以矩形的方式显示在屏幕上&#xff0c;View是用户界面控件的基础。View的继承层次关系如下图&#xff1a; 可以看到所有的界面控件都是View的子类。简单证实一下&#xff0c;每当你用findViewByIds(R.id.xx)时总要将其强转&#…

“大整数阶乖”问题的递推算法

/**//* 标题&#xff1a;<<系统设计师>>应试编程实例-[递推算法程序设计]作者&#xff1a;成晓旭时间&#xff1a;2002年09月11日(11:52:00-16:26:00)实现递推算法的大整数阶乖处理函数时间&#xff1a;2002年09月16日(18:38:00-20:02:00)实现“斐波那契数列”问…

RecycleView的详细介绍

一、RecycleView的简介 RecyclerView是一种新的视图组&#xff0c;目标是为任何基于适配器的视图提供相 似的渲染方式。该控件用于在有限的窗口中展示大量数据集&#xff0c;它被作为ListView和GridView控件的继承者。 那么有了ListView、GridView为什么还需要RecyclerView这…

[人物]USTC十大IT精英

【科大精英】张亚勤 微软全球副总裁1999年加盟微软亚洲研究院(原微软中国研究院)&#xff0c;现任微软亚洲研究院院长兼首席科学家。张博士1966年出生于山西太原&#xff0c;12岁考入中国科技大学少年班&#xff0c;23岁获得美国乔治华盛顿大学电气工程博士学位(1989)&#xff…

CardView的简单使用

一、CardView的简介 CardView继承自FrameLayout类&#xff0c;可以在一个卡片布局中一致性的显示内容&#xff0c;卡片可以包含圆角和阴影&#xff0c;这是CardView的最大的卖点。CardView是一个Layout&#xff0c;可以布局其他View。 CardView常用属性&#xff1a; card_view…

JAMstack:什么,为什么以及如何

介绍 (Introduction) Web development often involves the use of different development stacks, including the LAMP stack, the MEAN stack, the MERN stack, etc. JAMstack is another stack that offers some unique benefits to developers. This article will discuss t…

joi 参数验证_使用Joi进行节点API架构验证

joi 参数验证介绍 (Introduction) Imagine you are working on an API endpoint to create a new user, and some user data such as firstname, lastname, age and birthdate will need to be included in the request. Passing Sally in as value for age, or 53 for birthda…