使用Django模板和静态文件

使用Django模板和静态文件

在我开始使用Django教程时,我向您展示了如何让Django站点启动并运行。我们提供的模板是非常基础的。

这绝对不是你想要你的网站的样子。

django

你如何让你的网站看起来更好?简单!添加一些造型。在本教程中,我将向您展示如何添加一些CSS和JavaScript到您的Django模板,以使它们看起来更好。为此,您首先需要了解Django中静态文件的概念。


设置Django项目

我们设置我们的测试Django项目。首先,创建一个名为“ projects我的应用程序” 的文件夹。

$ mkdir projects && cd projects

在里面projects,让virtualenv我们用来为我们的应用程序的依赖创建一个环境。

$ virtualenv env --python python3

注意:

如果您没有virtualenv安装,请使用该命令进行安装pip install virtualenv。 一旦完成,通过运行activate shell脚本激活环境。

$ source env/bin/activate

如果该命令有效,您(env)的终端应该会看到一个提示。

#(env)~/projects
$

真棒!现在我们pip来安装Django我们的环境。

#(env)~/projects
$ pip install django

该命令应该将Django安装到您的环境中。在写作的时候,Django版本是1.10.4。

我们然后打电话给django-admin脚本来创建我们的Django应用程序。我们这样做:

#(env)~/projects
$ django-admin startproject djangotemplates

如果你检查你的projects文件夹结构,你应该有一个名为djangotemplatesDjango创建的新文件夹,除了env我们创建的早期文件夹。

cd成djangotemplates。

您的文件夹结构现在应该类似于:

djangotemplates
--djangotemplates
----__init__.py
----settings.py
----urls.py
----wsgi.py
--manage.py

完成。你现在准备开始了!


管理静态文件的设置

静态文件包括CSS,JavaScript和图像,您可能希望与您的网站一起提供。Django非常擅长如何应用静态文件。在本文中,我将展示如何将静态文件添加到Django应用程序。

打开settings.py内部djangotemplates文件夹中的文件。在文件的最底部,您应该看到这些行:

# djangotemplates/djangotemplates/settings.py

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/

STATIC_URL = '/static/'

这行告诉Django localhost:8000在搜索静态文件时将静态附加到基本URL(在我们的例子中)。在Django中,你可以在static任何你想要的地方找到一个文件夹。您甚至可以有多个static文件夹,例如每个应用程序中的一个文件夹。但是,为了简单起见,我将仅static在项目文件夹的根目录中使用一个文件夹。我们以后会创造一个。现在,我们在settings.py文件中添加一些行,看起来像这样。

# djangotemplates/djangotemplates/settings.py

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/

STATIC_URL = '/static/'

# Add these new lines
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

该STATICFILES_DIRS元组告诉Django在哪里查找不绑定到特定应用程序的静态文件。在这种情况下,我们只是告诉Django还要static在我们的根文件夹中调用的文件夹中找到静态文件,而不仅仅是在我们的应用程序中。

Django还提供了一种将静态文件收集到一个位置的机制,从而可以轻松地提供服务。使用该collectstatic命令,Django会在您的应用程序中查找所有静态文件,并将其收集到任何地方STATIC_ROOT。在我们的例子中,我们告诉Django,当我们运行时python manage.py collectstatic,将所有静态文件收集到staticfiles我们项目根目录下的一个文件夹中。此功能非常方便地提供静态文件,特别是在生产设置中。


应用程式设定

创建static与内部djangotemplates文件夹和manage.py文件在同一级别上调用的文件夹。你现在应该有这样的结构:

djangotemplates
--djangotemplates
----__init__.py
----settings.py
----urls.py
----wsgi.py
--static
--manage.py

在这个文件夹里面,我们将会有任何自定义的CSS和JS,我们选择写。在这一点上,让我们在静态文件夹中添加两个文件夹来保存我们的文件,一个被调用css,另一个被调用js。在里面css,创建一个文件main.css。main.js在js文件夹中也添加一个。您的静态文件夹应该如下所示:

--static
----css
------main.cs
----js
------main.js

一旦完成,让我们创建一个名为example我们将要使用的新的Django应用程序。你还记得怎么做吗?别担心,这很简单。

#(env)~/projects/djangotemplates
$ python manage.py startapp example

一旦完成,你应该有一个文件夹example旁边djangotemplates和static。当然,您仍然可以看到该manage.py文件。

djangotemplates
--djangotemplates
----__init__.py
----settings.py
----urls.py
----wsgi.py
--example
--static
--manage.py

我们需要告诉Django我们的新应用程序。转到内部djangotemplates文件夹,打开settings.py并寻找INSTALLED_APPS。添加example在其他应用程序之下。

# djangotemplates/djangotemplates/settings.py

DEBUG = True

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'example', # Add this line
]

回顾一下,我们现在有以下文件夹结构:

djangotemplates
--djangotemplates
----__init__.py
----settings.py
----urls.py
----wsgi.py
--example
----migrations
------__init__.py
----admin.py
----apps.py
----models.py
----tests.py
----views.py
--static
----css
------main.cs
----js
------main.js
--manage.py

定义网址

让我们定义一个URL来转到我们的新应用程序。让我们来编辑djangotemplates/djangotemplates/urls.py来实现。

# djangotemplates/djangotemplates/urls.py

from django.conf.urls import url, include # Add include to the imports here
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^', include('example.urls')) # tell django to read urls.py in example app
]

之后,在example应用程序文件夹中,创建一个新的文件,urls.py并添加以下代码:

# djangotemplates/example/urls.py

from django.conf.urls import url
from example import views

urlpatterns = [
    url(r'^$', views.HomePageView.as_view(), name='home'), # Notice the URL has been named
    url(r'^about/$', views.AboutPageView.as_view(), name='about'),
]

我们刚刚写的代码告诉Django将空路由(即localhost:8000)与调用的视图HomePageView和调用的视图的路由/about/进行匹配AboutPageView。记住,Django视图接受HTTP请求并返回HTTP响应。在我们的情况下,我们将使用TemplateView它返回一个主页模板,另一个用于关于页面。要做到这一点,在你的example应用程序文件夹中,创建另一个文件夹templates。里面的新templates文件夹,创建两个名为新文件index.html和about.html。您的example应用文件夹应该具有以下结构:

--example
----migrations
------__init__.py
----templates
------index.html
------about.html
----admin.py
----apps.py
----models.py
----tests.py
----urls.py
----views.py

在里面index.html粘贴以下代码:

<!-- djangotemplates/example/templates/index.html-->

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Welcome Home</title>
</head>
<body>
  <p>"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 
    Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
  </p>
  <a href="{% url 'home' %}">Go Home</a>
  <a href="{% url 'about' %}">About This Site</a>
</body>
</html>

将此代码添加到about.html:

<!-- djangotemplates/example/templates/about.html-->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>About Us</title>
</head>
<body>
  <p>
  We are a group of Django enthusiasts with the following idiosyncrasies:

  <ol>
    <li>We only eat bananas on Saturdays.</li>
    <li>We love making playing football on rainy days.</li>
  </ol>
  </p>
  <a href="{% url 'home' %}">Go Home</a>
  <a href="{% url 'about' %}">About This Site</a>
</body>
</html>

请注意我们如何指向我们的链接Go Home和About This Site模板。我们可以使用Django的自动URL反向查找,因为我们在我们的URL中命名了我们的URL urls.py。整齐啊!

我们将在下一节中看到这段代码的效果。


连接视图

我们添加最终的代码来提供我们的模板。我们需要编辑djangotemplates/example/views.py这个。

# djangotemplates/example/views.py
from django.shortcuts import render
from django.views.generic import TemplateView # Import TemplateView

# Add the two views we have been talking about  all this time :)
class HomePageView(TemplateView):
    template_name = "index.html"

class AboutPageView(TemplateView):
    template_name = "about.html"

现在我们可以运行我们的应用 我们首先需要使Django的默认迁移,因为这是我们第一次运行我们的应用程序。

#(env)~/projects/djangotemplates
$ python manage.py migrate

接着, 启动您的服务器。

#(env)~/projects/djangotemplates
$ python manage.py runserver

打开浏览器并导航到http://localhost:8000。你应该可以看到我们的主页。

home page

点击底部的链接应该可以在页面之间导航。以下是关于页面:about page


模板继承

让我们将焦点转移到example应用程序文件夹中的templates文件夹。目前,它包含两个模板,index.html和about.html。

我们希望这两个模板都包含一些CSS。而不是在两者中重写相同的代码,Django允许我们创建一个他们将继承的基础模板。这样,当我们需要修改任何共享的东西时,我们无法在我们的模板中编写很多重复的代码。

让我们现在创建基础模板。创建一个名为文件base.html在djangotemplates/example/templates。在里面写这个代码:

<!-- djangotemplates/example/templates/base.html -->

{% load static %}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>
      Django Sample Site - {% block title %}{% endblock %}
    </title>

    <script src="{% static 'js/main.js' %}"></script> <!-- This is how to include a static file -->
    <link rel="stylesheet" href="{% static 'css/main.css' %}" type="text/css" />
  </head>
  <body>
    <div class="container">
      {% block pagecontent %}
      {% endblock %}
    </div>
  </body>
</html>

该文件中的第一行{% load static %}使用Django的特殊模板标记语法来告诉模板引擎使用static该模板中文件夹中的文件。

在标题标签中,我们使用一个Django块。这意味着在从该基本模板继承的任何Django模板中,任何位于所指定的块内的HTML title将被插入到标题块中。身体标签的pagecontent块也是一样。如果这听起来很混乱,别担心。你会很快看到它。

如果您没有运行Django服务器,请python manage.py runserver在终端中执行。去http://localhost:8000。你应该看到以前的模板。

template

现继承基础模板。 然后,编辑index.html模板。

<!-- djangotemplates/example/templates/index.html -->

{% extends 'base.html' %} <!-- Add this for inheritance -->

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Welcome Home</title>
</head>
<body>
    <p>"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
      Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
      Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 
      Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
    </p>
    <a href="{% url 'home' %}">Go Home</a>
    <a href="{% url 'about' %}">About This Site</a>
</body>
</html>

在浏览器中重新载入页面。没有什么出现!这是因为Django希望将内容写入我们在基本模板中定义的块中,以便它们可以被渲染。编辑index.html添加块:

<!-- djangotemplates/example/templates/index.html -->

{% extends 'base.html' %}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>{% block title %}Welcome Home {% endblock %}</title>
</head>
<body>
  {% block pagecontent %}
    <p>"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
      Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
      Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 
      Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
    </p>
    <a href="{% url 'home' %}">Go Home</a>
    <a href="{% url 'about' %}">About This Site</a>
  {% endblock %}
</body>
</html>

在浏览器中重新加载页面,瞧瞧!您的内容应再次出现!

home page

我们也可以使用相同的基础模版。然后,编辑about.html模板。

<!-- djangotemplates/example/templates/about.html -->

{% extends 'base.html' %} <!-- Add this for inheritance -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}About Us {% endblock %}</title>
</head>
<body>
  {% block pagecontent %}
    <p>
    We are a group of Django enthusiasts with the following idiosyncrasies:

    <ol>
        <li>We only eat bananas on Saturdays.</li>
        <li>We love making playing football on rainy days.</li>
    </ol>
    </p>
    <a href="{% url 'home' %}">Go Home</a>
    <a href="{% url 'about' %}">About This Site</a>
  {% endblock %}
</body>
</html>

您现在应该在“关于”页面上看到这一点:

about page

这与以前完全一样!

然而,现在,由于两个模板都是从基础模板继承的,所以我可以轻松地对它们进行风格化 打开main.css你的css文件夹并添加这些样式:

.container {
    background: #eac656;
    margin: 10 10 10 10;
    border: 3px solid black;
}

这将使我们正在加载我们的内容的容器div的样式。刷新浏览器 你应该看到这个:

主页:

home page

关于页面:

about page


使用来自视图的数据渲染模板

您可以使用Django的模板引擎以非常强大的方式显示数据。在本节中,我将创建一个将数据传递到模板中的Django视图。然后我将向您展示如何访问模板中的数据并将其显示给用户。

首先,views.py在example应用程序文件夹中打开。我们将添加一个新视图,将数据投入到我们尚未存在的data.html模板中。修改views.py文件看起来像这样:

# djangotemplates/example/views.py

from django.shortcuts import render
from django.views.generic import TemplateView

class HomePageView(TemplateView):
    template_name = "index.html"

class AboutPageView(TemplateView):
    template_name = "about.html"

# Add this view
class DataPageView(TemplateView):
    def get(self, request, **kwargs):
        # we will pass this context object into the
        # template so that we can access the data
        # list in the template
        context = {
            'data': [
                {
                    'name': 'Celeb 1',
                    'worth': '3567892'
                },
                {
                    'name': 'Celeb 2',
                    'worth': '23000000'
                },
                {
                    'name': 'Celeb 3',
                    'worth': '1000007'
                },
                {
                    'name': 'Celeb 4',
                    'worth': '456789'
                },
                {
                    'name': 'Celeb 5',
                    'worth': '7890000'
                },
                {
                    'name': 'Celeb 6',
                    'worth': '12000456'
                },
                {
                    'name': 'Celeb 7',
                    'worth': '896000'
                },
                {
                    'name': 'Celeb 8',
                    'worth': '670000'
                }
            ]
        }

        return render(request, 'data.html', context)

我们使用与我们用于渲染其他模板的相同的视图。但是,我们现在将一个context对象传递给render方法。上下文中定义的键值对将在渲染的模板中可用,我们可以像任何其他列表一样遍历它们。

要完成此操作,请转到应用程序中的urls.py文件,howdy并为新视图添加URL模式,使其如下所示:

# djangotemplates/example/urls.py

from django.conf.urls import url
from example import views

urlpatterns = [
    url(r'^$', views.HomePageView.as_view(), name='home'),
    url(r'^about/$', views.AboutPageView.as_view(), name='about'),
    url(r'^data/$', views.DataPageView.as_view(), name='data'),  # Add this URL pattern
]

最后,我们来创建模板。在templates文件夹中,创建一个文件,data.html并在其中写入此代码。

<!-- djangotemplates/example/templates/data.html -->

{% extends 'base.html' %}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    {% block pagecontent %}
    <div class="table-div">
    <!-- We will display our data in a normal HTML table using Django's
    template for-loop to generate our table rows for us-->
      <table class="table">
        <thead>
          <tr>
            <th>Celebrity Name</th>
            <th>Net Worth</th>
          </tr>
        </thead>
        <tbody>
          {% for celebrity in data %}
            <tr>
              <td>{{ celebrity.name }}</td>
              <td>{{ celebrity.worth }}</td>
            </tr>
          {% endfor %}
        </tbody>
      </table>
    </div>
    {% endblock %}
  </body>
</html>

在这里data.html,您可以看到我们使用基本上是for循环来浏览数据列表。在Django模板中绑定值是使用{{}}大括号,就像在AngularJS中一样。

随着你的服务器运行,去看http://localhost:8000/data/模板。

data


模板中插入模板片段

我们现在有三个模板index.html,about.html和data.html。让我们用一个简单的导航栏将它们连在一起。首先,让我们在另一个HTML模板中编写导航栏的代码。

在example应用程序的templates文件夹中,创建一个名为的新文件夹partials。在里面,创建一个名为的文件nav-bar.html。模板文件夹结构现在应该是这样的:

templates
----index.html
----about.html
----data.html
----partials
------nav-bar.html

编辑nav-bar.html部分,使其包含此代码:

<!-- djangotemplates/example/templates/partials/nav-bar.html -->

<div class="nav">
  <a href="{% url 'home' %}">Go Home</a>
  <a href="{% url 'about' %}">About This Site</a>
  <a href="{% url 'data' %}">View Data</a>
</div>

在模板中包含片段非常简单。我们使用includesDjango的模板引擎提供的关键字。继续修改index.html为:

<!-- djangotemplates/example/templates/index.html -->

{% extends 'base.html' %}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>{% block title %}Welcome Home {% endblock %}</title>
</head>
<body>
  {% block pagecontent %}
    <p>"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
      Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
      Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 
      Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
    </p>
    {% include 'partials/nav-bar.html' %} <!--Add this-->

    <!-- Remove these two lines -- >
    <!-- <a href="{% url 'home' %}">Go Home</a> -->
    <!-- <a href="{% url 'about' %}">About This Site</a> -->
  {% endblock %}
</body>
</html>

修改about.html为:

<!-- djangotemplates/example/templates/about.html -->

{% extends 'base.html' %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}About Us {% endblock %}</title>
</head>
<body>
  {% block pagecontent %}
    <p>
    We are a group of Django enthusiasts with the following idiosyncrasies:

    <ol>
        <li>We only eat bananas on Saturdays.</li>
        <li>We love making playing football on rainy days.</li>
    </ol>
    </p>
    {% include 'partials/nav-bar.html' %} <!--Add this-->

    <!-- Remove these two lines -- >
    <!-- <a href="{% url 'home' %}">Go Home</a> -->
    <!-- <a href="{% url 'about' %}">About This Site</a> -->
  {% endblock %}
</body>
</html>

最后修改data.html为:

<!-- djangotemplates/example/templates/data.html -->

{% extends 'base.html' %}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    {% block pagecontent %}
    <div class="table-div">
      <table class="table">
        <thead>
          <tr>
            <th>Celebrity Name</th>
            <th>Net Worth</th>
          </tr>
        </thead>
        <tbody>
          {% for celebrity in data %}
            <tr>
              <td>{{ celebrity.name }}</td>
              <td>{{ celebrity.worth }}</td>
            </tr>
          {% endfor %}
        </tbody>
      </table>
    </div>
    {% include 'partials/nav-bar.html' %} <!--Add this-->
    {% endblock %}
  </body>
</html>

此刻检查我们的工作!打开浏览器并导航到http://localhost:8000。你应该看到这个:

home page

所有的页面现在都与导航栏相关联,所以您可以轻松地通过它们前后浏览,所有这些都以最小的代码编写。这是data.html模板:

data page

这里是about.html

about page

注意:

我已经添加了以下CSS来浏览导航栏中的链接。随意使用或玩自己的风格:

// djangtotemplates/static/css/main.css

.container {
    background: #eac656;
    margin: 10 10 10 10;
    border: 3px solid black;
}

.nav a {
    background: #dedede;
}

过滤器

过滤器将数据管道传输给它们并以格式化的方式输出。Django模板可以访问humanize过滤器的集合,使数据更加人性化。让我们通过使用其中一些过滤器,使数据模板中的名人的网络域变得更加易读。

要使用Django的人性化过滤器,您首先需要编辑一些设置。打开djangotemplates/settings.py并编辑INSTALLED_APPS列表:

# djangotemplates/djangotemplates/settings.py

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.humanize', # Add this line. Don't forget the trailing comma
    'example',
]

我们现在可以在我们的模板中使用过滤器。我们将使用intcomma过滤器来大量添加逗号,使其更容易阅读。我们来修改data.html一下:

<!-- djangotemplates/example/templates/data.html -->

{% extends 'base.html' %}
{% load humanize %} <!-- Add this-->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    {% block pagecontent %}
    <div class="table-div">
      <table class="table">
        <thead>
          <tr>
            <th>Celebrity Name</th>
            <th>Net Worth</th>
          </tr>
        </thead>
        <tbody>
          {% for celebrity in data %}
            <tr>
              <td>{{ celebrity.name }}</td>
              <td>$ {{ celebrity.worth | intcomma }}</td> <!--Modify this line-->
            </tr>
          {% endfor %}
        </tbody>
      </table>
    </div>
    {% include 'partials/nav-bar.html' %}
    {% endblock %}
  </body>
</html>

当再一次访问http://localhost:8000/data/时,你应该有一个更友好的净值列表:

data page

humanize包装中包含更多的过滤器。在这里阅读他们


收集静态文件

记得我们谈论收集静态文件吗?尝试以下命令:

python manage.py collectstatic

您应该会看到如下提示:

You have requested to collect static files at the destination
location as specified in your settings:

      /Users/amos/projects/djangotemplates/staticfiles

This will overwrite existing files!
Are you sure you want to do this?

Type 'yes' to continue, or 'no' to cancel: 

来吧,说yes。

该命令将告诉Django通过所有项目文件夹,查找所有静态文件并将它们存储在一个位置(我们在设置中定义的静态根目录)。这是非常有效的,特别是如果您将您的站点部署到生产。

运行该命令时collectstatic,应该会看到一个名为staticfiles在项目文件夹根目录中创建的新文件夹。您可以通过编辑项目settings.py文件中的静态根设置来将此位置更改为其他位置。要使用这些staticfiles,在你的模板中你会说load staticfiles而不是load static。一切都和使用上一个static文件夹一样。


结论

祝贺本教程结束!现在,您应该对Django模板的工作原理有更详细的了解。如果您需要更深入的信息,请记住文档是您的朋友。您可以在这里找到本教程的完整代码。确保在下面的意见中留下任何想法,问题或疑虑。

 教程来源: scotch.io

评论 0