作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
Arjaan是一名高级工程师和数据科学家,他为国际银行和保险公司创建了专注于Rasa的关键任务云解决方案. 他设计并教授大规模Kubernetes解决方案.
这是关于在基于django的项目中利用pydantic的系列文章的第二部分. 在本系列的第一部分中,我们重点介绍了pydantic对Python类型提示的使用 简化Django设置管理.
开发者可能是他们自己最大的敌人. 我见过无数工程师在与生产环境不匹配的系统上进行开发的例子. 这种不协调导致了额外的工作,并且直到开发过程的后期才捕捉到系统错误. 调整这些设置最终将简化持续部署. With this in mind, 我们将在Django开发环境中创建一个示例应用程序, 通过Docker简化, pydantic, and conda.
一个典型的开发环境使用:
Pydantic和Django适用于简单和复杂的项目. 下面的步骤展示了一个简单的解决方案,强调了如何镜像我们的环境.
在开始编写代码或安装开发系统之前,让我们先创建一个本地Git存储库:
mkdir hello-visitor
cd hello-visitor
git init
We’ll start with a basic Python .gitignore
file in the repository root. 在本教程中,我们将在添加不希望Git跟踪的文件之前添加该文件.
Django需要一个关系数据库,默认情况下使用SQLite. 对于关键任务数据存储,我们通常避免使用SQLite,因为它不能很好地处理并发用户访问. 大多数开发人员选择更典型的生产数据库,如PostgreSQL. 无论如何,我们应该在开发和生产中使用相同的数据库. 这个架构任务是 The Twelve-factor App.
幸运的是,操作本地PostgreSQL实例 Docker and Docker Compose is a breeze.
为了避免污染根目录,我们将把与docker相关的文件放在单独的子目录中. 我们将从创建一个Docker Compose文件来部署PostgreSQL开始:
# docker-services / docker-compose.yml
version: "3.9"
services:
db:
image: "postgres:13.4"
env_file: .env
volumes:
- hello-visitor-postgres: / var / lib / postgresql /数据
ports:
- ${POSTGRES_PORT}:5432
volumes:
hello-visitor-postgres:
Next, we’ll create a docker-compose
环境文件来配置PostgreSQL容器:
# docker-services/.env
POSTGRES_USER=postgres
POSTGRES_PASSWORD = MyDBPassword123
#维护数据库
POSTGRES_DB=postgres
#向localhost公开的端口
POSTGRES_PORT=5432
现在已经定义和配置了数据库服务器. 让我们在后台启动容器:
——项目目录docker-services/ up
重要的是要注意在前面的命令中使用了sudo. 这是必须的,除非 specific steps 在我们的开发环境中是遵循的吗.
让我们使用一个标准的工具套件连接和配置PostgreSQL。 pgAdmin4. 我们将使用与前面在环境变量中配置的相同的登录凭据.
现在让我们创建一个名为 hello_visitor
:
数据库就绪后,我们就可以安装编程环境了.
我们现在需要建立一个隔离 Python 环境和所需的依赖项. 为了简化设置和维护,我们选择 Miniconda.
让我们创建并激活conda环境:
Conda create——name hello-visitor python=3.9
请激活你好,访客
现在,我们要创建一个文件, hello-visitor /需求.txt
,枚举我们的Python依赖项:
django
# PostgreSQL数据库适配器
psycopg2
# Pushes .将键值对放入环境变量中:
python-dotenv
pydantic
#实用程序库读取数据库连接信息:
dj-database-url
# Static file caching:
whitenoise
# Python WSGI HTTP Server
gunicorn
接下来,我们将要求Python安装这些依赖项:
cd hello-visitor
PIP安装-r要求.txt
现在应该安装依赖项,为应用程序开发工作做准备.
我们将通过第一次运行脚手架我们的项目和应用程序 django-admin
,然后运行它生成的文件, manage.py
:
#从' hello-visitor '目录
mkdir src
cd src
为Django项目生成启动代码.
Django-admin启动项目hello_visitor .
为我们的Django应用生成启动代码.
python manage.py startapp homepage
接下来,我们需要配置Django来加载我们的项目. The settings.py
文件要求对 INSTALLED_APPS
数组来注册我们新创建的 homepage
app:
# src / hello_visitor /设置.py
# ...
INSTALLED_APPS = [
"homepage.apps.HomepageConfig",
"django.contrib.admin",
# ...
]
# ...
使用pydantic和Django设置方法 the first installment,我们需要为开发系统创建一个环境变量文件. 我们将把当前设置移到这个文件中,如下所示:
src/.env
保持我们的开发环境设置.src / hello_visitor /设置.py
and add them to src/.env
.settings.py
file.Our environment file, src/.env
, should look like this:
DATABASE_URL = postgres: / / postgres: MyDBPassword123@localhost: 5432 / hello_visitor
DATABASE_SSL=False
SECRET_KEY = " django-insecure-sackl&7(1hc3+%#*4e=)^q3qiw!hnnui*-^($o8t@2^^qqs=%i"
DEBUG=True
DEBUG_TEMPLATES=True
USE_SSL=False
ALLOWED_HOSTS='[
"localhost",
"127.0.0.1",
"0.0.0.0"
]'
我们将使用pydantic配置Django从环境变量中读取设置, with this code snippet:
# src / hello_visitor /设置.py
import os
from pathlib import Path
from pydantic import (
BaseSettings,
PostgresDsn,
EmailStr,
HttpUrl,
)
import dj_database_url
#在项目内部构建路径:BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
类SettingsFromEnvironment (BaseSettings):
定义环境变量及其类型和可选默认值"""
# PostgreSQL
DATABASE_URL: PostgresDsn
DATABASE_SSL: bool = True
# Django
SECRET_KEY: str
DEBUG: bool = False
DEBUG_TEMPLATES: bool = False
USE_SSL: bool = False
ALLOWED_HOSTS: list
class Config:
定义pypytic环境加载的配置
env_file = str(BASE_DIR / ".env")
case_sensitive = True
config = SettingsFromEnvironment()
os.environ["DATABASE_URL"] = config . conf.DATABASE_URL
DATABASES = {
“默认”:dj_database_url.配置(conn_max_age = 600, ssl_require =配置.DATABASE_SSL)
}
SECRET_KEY = config.SECRET_KEY
DEBUG = config.DEBUG
DEBUG_TEMPLATES = config.DEBUG_TEMPLATES
USE_SSL = config.USE_SSL
ALLOWED_HOSTS = config.ALLOWED_HOSTS
# ...
如果您在完成之前的编辑后遇到任何问题,请比较我们的制作 settings.py
file with the 源代码存储库中的版本.
我们的应用程序跟踪并显示主页访问者计数. We need a model 来保持计数,然后使用 Django的对象关系映射器 (ORM)通过数据迁移初始化单个数据库行.
First, we’ll create our VisitCounter
model:
# hello-visitor / src /网页/模型.py
"""定义模型"""
from django.db import models
类VisitCounter(模型.Model):
"""访问柜台的ORM """
count = models.IntegerField()
@staticmethod
def insert_visit_counter ():
"""用一个访问计数器填充数据库. 从数据迁移调用."""
visit_counter = VisitCounter(count=0)
visit_counter.save()
def __str__(self):
访问次数:{self.count}"
接下来,我们将触发迁移来创建我们的数据库表:
# in the `src` folder
python manage.py makemigrations
python manage.py migrate
To verify that the homepage_visitcounter
表存在时,我们可以在pgAdmin4中查看数据库.
接下来,我们需要将初始值放入 homepage_visitcounter
table. 让我们用Django脚手架创建一个单独的迁移文件来完成:
#从'src'目录
python manage.Py makemigration——空主页
我们将调整创建的迁移文件以使用 VisitCounter.insert_visit_counter
方法,我们在本节开头定义:
# src /网页/迁移/ 0002 _auto _-------_----.py
#注意:破折号依赖于执行时间.
from django.db import migrations
from ..模型导入VisitCounter
Def insert_default_items(apps, _schema_editor):
"""用一个访问计数器填充数据库."""
#要了解应用程序,请参阅:
# http://docs.djangoproject.com/en/3.2 /主题/迁移/ #数据迁移
VisitCounter.insert_visit_counter()
类迁移(迁移.Migration):
"""Runs a data migration."""
dependencies = [
(“主页”、“0001 _initial”),
]
operations = [
migrations.RunPython (insert_default_items),
]
现在我们已经准备好执行这个修改后的迁移 homepage
app:
#从'src'目录
python manage.py migrate homepage
让我们通过查看表的内容来验证迁移是否正确执行:
We see that our homepage_visitcounter
表已经存在,并且已经用初始访问计数0填充. 处理好数据库之后,我们将专注于创建UI.
我们需要实现UI的两个主要部分:视图和模板.
We create the homepage
视图以增加访问者计数, save it to the database, 并将该计数传递给模板以显示:
# src/homepage/views.py
from django.快捷方式导入get_object_or_404,渲染
from .模型导入VisitCounter
def index(request):
"""查看为应用程序主页面."""
VisitCounter = get_object_or_404(VisitCounter, pk=1)
visit_counter.count += 1
visit_counter.save()
Context = {"visit_counter": visit_counter}
返回渲染请求,“主页/索引”.html", context)
我们的Django应用程序需要监听目标为 homepage
. 为了配置这个设置,我们将添加这个文件:
# src/homepage/urls.py
"""Defines urls"""
from django.urls import path
from . import views
#应用的URLconf的命名空间
App_name = "主页" # pylint: disable=invalid-name
urlpatterns = [
path("", views.index, name="index"),
]
For our homepage
申请要送达,我们必须在不同的地方注册 urls.py
file:
# src/hello_visitor/urls.py
from django.contrib import admin
from django.url导入包括,路径
urlpatterns = [
路径(" ",包括(“主页.urls")),
path("admin/", admin.site.urls),
]
我们项目的基本HTML模板将保存在一个新文件中, src /模板/布局/基地.html
:
{% load static %}
Hello, visitor!
{% block main %}{% endblock %}
我们将扩展基本模板 homepage
app in a new file, src /模板/网页/索引.html
:
{% extends "layouts/base.html" %}
{% block main %}
Hello, visitor {{ visit_counter.count }}!
{% endblock %}
创建UI的最后一步是告诉Django在哪里可以找到这些模板. Let’s add a TEMPLATES['DIRS']
dictionary item to our settings.py
file:
# src / hello_visitor /设置.py
TEMPLATES = [
{
...
'DIRS': [BASE_DIR / 'templates'],
...
},
]
我们的用户界面现在已经实现,我们几乎准备好测试应用程序的功能了. Before we do our testing, 我们需要准备好环境的最后一部分:静态内容缓存.
避免在我们的开发系统上走架构上的捷径, 我们将配置静态内容缓存来反映我们的生产环境.
我们将把项目的所有静态文件保存在一个目录中, src/static
,并指示Django在部署前收集这些文件.
我们将在应用程序中使用Toptal的徽标 favicon
and store it as src/static/favicon.ico
:
# from `src` folder
mkdir static
cd static
wget http://frontier-assets.likethemoviesband.com/83b2f6e0d02cdb3d951a75bd07ee4058.png
83 mv b2f6e0d02cdb3d951a75bd07ee4058.png favicon.ico
接下来,我们将配置Django来收集静态文件:
# src / hello_visitor /设置.py
#静态文件(CSS, JavaScript,图像)
# a la http://docs.djangoproject.com/en/3.2/howto/static-files/
#
我们将存储静态文件的源位置
STATICFILES_DIRS = [BASE_DIR / "static"]
#构建Django收集所有静态文件的输出位置
STATIC_ROOT = BASE_DIR / "staticfiles"
STATIC_ROOT.mkdir(exist_ok=True)
引用位于STATIC_ROOT中的静态文件时使用的# URL.
STATIC_URL = "/static/"
STATICFILES_STORAGE = "白噪声.storage.CompressedManifestStaticFilesStorage”
We only want to store our original static files in the source code repository; we do not want to store the production-optimized versions. 让我们把后者加到 .gitignore
with this simple line:
staticfiles
我们的源代码库正确地存储了所需的文件, 现在我们需要配置缓存系统来处理这些静态文件.
在生产环境中(因此在开发环境中也是如此),我们将使用 WhiteNoise 更有效地为Django应用程序的静态文件提供服务.
我们将WhiteNoise注册为中间件,方法是向我们的 src / hello_visitor /设置.py
file. 注册顺序有严格的定义,并且 WhiteNoiseMiddleware
必须紧接在 SecurityMiddleware
:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
# ...
]
STATICFILES_STORAGE = '白噪声.storage.CompressedManifestStaticFilesStorage”
现在应该在我们的开发环境中配置静态文件缓存, 使我们能够运行应用程序.
我们已经编写了一个完整的应用程序,现在可以用下面的命令启动Django的嵌入式开发web服务器:
# in the `src` folder
python manage.py runserver
When we navigate to http://localhost:8000
,每次刷新页面,计数都会增加:
现在,我们有了一个可以工作的应用程序,当我们刷新页面时,它将增加其访问计数.
本教程涵盖了在美观的环境中创建工作应用程序所需的所有步骤 Django 与生产相匹配的开发环境. 在第3部分中,我们将介绍将应用程序部署到其生产环境. 我们的额外练习也值得探索一下,这些练习突出了Django和pydantic的优点:它们包含在 code-complete repository 对于这个pydantic教程.
Toptal Engineering博客向 Stephen Davidson 为了检查和测试本文中提供的代码示例.
pydantic开箱即用,比其他验证库更快. 官方pydantic文档中提供了已发布的基准测试.
Yes. Pydantic是一个普通的Python包,可以简单地通过pip安装它来与Django一起使用.
我们将“环境”定义为开发或托管应用程序的系统. In this case, 最好的开发环境被定义为与生产中使用的环境相匹配.
面向用户的网站应该始终运行在一个安全的环境中,只有在新代码经过广泛测试后才会更新新代码. 新代码是在单独的开发环境中创建的,并且在将其部署到生产环境之前,通常在一个或多个登台环境中进行测试.
Arjaan是一名高级工程师和数据科学家,他为国际银行和保险公司创建了专注于Rasa的关键任务云解决方案. 他设计并教授大规模Kubernetes解决方案.
世界级的文章,每周发一次.
世界级的文章,每周发一次.
Join the Toptal® community.
\n