Python系列(11)- 使用 Pipenv 搭建 Django + Rest Framework 开发环境
Django 是一个开放源代码的 Web 应用框架,用 Python 语言编写的。采用了 MTV 的框架模式,即模型 Model,模版 Template 和视图 View。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是 CMS(内容管理系统)软件。
Django:http://www.djangoproject.com
GitHub:https://github.com/django
Django REST framework (DRF) 是一个用于构建 Web API 的强力工具集,是一个基于 Django 的 Python Web 框架,它为开发人员提供了一套快速开发 RESTful API 的工具,它能够自动化 API 可视化、文档化,实现接口的自动化测试以及自动化的API路由、序列化、视图、验证、分页、版本管理、认证等等功能。DRF 简化了 API 的开发,并提供了一系列的工具来构建高质量的 API。
Django REST framework:https://www.django-rest-framework.org/
Pipenv 是一个创建和管理 Python 项目虚拟环境的管理工具,它结合了 pip 和 virtualenv 的优点,pipenv 的安装配置请参考 “Python系列(1)- Python 简介、环境配置、开发/管理工具、Python 虚拟环境” 的 “Python 虚拟环境” 部分。
1. 系统环境
操作系统: Windows 10 Home
命令行控制台:Windows PowerShell
Python: 3.8.5
Pipenv: 2024.0.1
2. 创建 Pipenv 虚拟环境
Pipenv 虚拟环境是基于目录,即目录级别的虚拟环境,在目录下创建一个虚拟环境。
新建 D:\pipenv_djangodemo 目录,并进入目录:
D:\pipenv_djangodemo
创建 Python 3.8 虚拟环境,运行如下命令:
D:\pipenv_djangodemo> pipenv install --python 3.8
Creating a virtualenv for this project... Pipfile: D:\pipenv_djangodemo\Pipfile Using C:/Users/admin/AppData/Local/Programs/Python/Python38/python.exe (3.8.5) to create virtualenv... [=== ] Creating virtual environment...created virtual environment CPython3.8.5.final.0-64 in 7058ms creator CPython3Windows(dest=D:\pipenv_djangodemo\.venv, clear=False, no_vcs_ignore=False, global=False) seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=C:\Users\admin\AppData\Local\pypa\virtualenv) added seed packages: pip==24.2, setuptools==72.1.0, wheel==0.44.0 activators BashActivator,BatchActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator Successfully created virtual environment! ...
查看虚拟环境信息:
# 当前虚拟环境的目录
D:\pipenv_djangodemoo> pipenv --venv
D:\pipenv_djangodemo\.venv
# 当前虚拟环境使用的 Python 解释器
D:\pipenv_djangodemo> pipenv --py
D:\pipenv_djangodemo\.venv\Scripts\python.exe
3. 创建 Django 项目
在虚拟环境内安装 Django 4.0,运行如下命令:
D:\pipenv_djangodemo> pipenv install django==4.0 Installing django==4.0... Resolving django==4.0... Added django to Pipfile's [packages] ... ' Installation Succeeded ... D:\pipenv_djangodemo> pipenv run django-admin --version # 查看 Django 版本 4.0
注:在一个虚拟环境内只需要安装一次 Django, 已经安装过直接运行 django-admin 命令创建 Django 项目。
在虚拟环境内使用 django-admin 命令创建 djangoRestDemo 项目,运行如下命令:
D:\pipenv_djangodemo> pipenv run django-admin startproject 'djangoRestDemo' D:\pipenv_djangodemo> ls 目录: D:\pipenv_djangodemo Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 2024/9/2 12:22 .venv d----- 2024/9/2 12:32 djangoRestDemo -a---- 2024/9/2 12:22 218 Pipfile -a---- 2024/9/2 12:23 6249 Pipfile.lock D:\pipenv_djangodemo> ls djangoRestDemo 目录: D:\pipenv_djangodemo\djangoRestDemo Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 2024/9/2 12:32 djangoRestDemo -a---- 2024/9/2 12:38 0 db.sqlite3 -a---- 2024/9/2 12:32 692 manage.py
运行 djangoRestDemo 项目:
D:\pipenv_djangodemo> pipenv run python djangoRestDemo/manage.py runserver Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. September 02, 2024 - 12:38:06 Django version 4.0, using settings 'djangoRestDemo.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK.
或进入 djangoRestDemo 目录,运行项目:
D:\pipenv_djangodemo> cd djangoRestDemo D:\pipenv_djangodemo\djangoRestDemo> pipenv run python manage.py runserver ... D:\pipenv_djangodemo\djangoRestDemo> pipenv --venv D:\pipenv_djangodemo\.venv
注:在子目录下运行 pipenv 命令,pipenv 命令会自动查找本级和上级目录是否有 .venv 目录,本文测试了 3 级子目录下运行 pipenv 可以正常运行。
使用浏览器访问 http://127.0.0.1:8000/,显示 django 项目默认页面内容:
The install worked successfully! Congratulations!
You are seeing this page because DEBUG=True is in your settings file and you have not configured any URLs.
4. 添加 Django Rest Framework
我们在上文 djangoRestDemo 项目基础上,添加 Django Rest Framework,具体步骤如下。
1) 安装 Django Rest Framework
在虚拟环境内安装 Django Rest Framework,运行如下命令:
D:\pipenv_djangodemo> pipenv install djangorestframework Installing djangorestframework... Resolving djangorestframework... Added djangorestframework to Pipfile's [packages] ... ' Installation Succeeded ... D:\pipenv_djangodemo> pipenv run pip show djangorestframework # 查看 Django Rest Framework 安装包信息 Name: djangorestframework Version: 3.15.1 Summary: Web APIs for Django, made easy. Home-page: https://www.django-rest-framework.org/ Author: Tom Christie Author-email: tom@tomchristie.com License: BSD Location: d:\pipenv_djangodemo\.venv\lib\site-packages Requires: backports.zoneinfo, django Required-by:
注:在一个虚拟环境内只需要安装一次 Django Rest Framework。
2) 添加一个 Django app
D:\pipenv_djangodemo\djangoRestDemo> pipenv run python manage.py startapp 'restapi' D:\pipenv_djangodemo\djangoRestDemo> ls restapi 目录: D:\pipenv_djangodemo\djangoRestDemo\restapi Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 2024/9/2 13:37 migrations -a---- 2024/9/2 13:37 66 admin.py -a---- 2024/9/2 13:37 152 apps.py -a---- 2024/9/2 13:37 60 models.py -a---- 2024/9/2 13:37 63 tests.py -a---- 2024/9/2 13:37 66 views.py -a---- 2024/9/2 13:37 0 __init__.py
注:一个 Django 项目下面可以有很多个 app (应用),把不同功能放在不同 app,可以提高程序结构的清晰度和代码的可读性。
3) 修改 djangoRestDemo/settings.py 文件
INSTALLED_APPS = [ ... 'rest_framework', 'restapi', ] ...
4) 修改 djangoRestDemo/urls.py 文件
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('v1/', include('restapi.urls')), ]
5) 修改 restapi/views.py 文件
from django.http import JsonResponse from rest_framework import generics, status from rest_framework.response import Response def demo(request): data = {'key': 'value'} return JsonResponse(data) class Test(generics.RetrieveAPIView): def retrieve(self, request, *args, **kwargs): data = { 'key2': 'value2'} return Response(data, status=status.HTTP_200_OK)
6) 创建 restapi/urls.py 文件
from django.urls import path, include from restapi import views urlpatterns = [ path('demo/', views.demo), path('demo2/', views.Test.as_view()), ]
7) 运行
D:\pipenv_djangodemo\djangoRestDemo> pipenv run python manage.py runserver
...
使用浏览器访问 http://127.0.0.1:8000/v1/demo/,显示如下内容:
{"key": "value"}
访问 http://127.0.0.1:8000/v1/demo2/,显示 Test 的 Rest API 管理页面。
可以直接访问 http://127.0.0.1:8000/v1/demo2/?format=json,显示内容如下:
{"key2":"value2"}
5. 添加 MySQL
我们继续在上文 djangoRestDemo 项目基础上,添加 MySQL,具体步骤如下。
1) 安装 mysqlclient
在虚拟环境内安装 mysqlclient,运行如下命令:
D:\pipenv_djangodemo> pipenv install mysqlclient Installing mysqlclient... Resolving mysqlclient... Added mysqlclient to Pipfile's [packages] ... Installation Succeeded ... D:\pipenv_djangodemo> pipenv run pip show mysqlclient # 查看 mysqlclient 安装包信息 Name: mysqlclient Version: 2.2.4 Summary: Python interface to MySQL Home-page: Author: Author-email: Inada Naoki <songofacandy@gmail.com> License: GNU General Public License v2 (GPLv2) Location: d:\workshop\projects-django\pipenv_djangodemo\.venv\lib\site-packages Requires: Required-by:
注:在一个虚拟环境内只需要安装一次 mysqlclient 。
2) 修改 djangoRestDemo/settings.py 文件
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'restdemo', 'USER': 'root', 'PASSWORD': '123456', 'HOST': 'localhost', 'PORT': '3306', } }
注:手动创建一个 MySQL 空数据库 restdemo。
3) 修改 restapi/models.py 文件
from django.db import models class User(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=50, blank=True, default='') email = models.CharField(max_length=100, blank=True, default='') comments = models.CharField(max_length=100, blank=True, default='') created = models.DateTimeField(auto_now_add=True) class Meta: ordering = ('created',)
4) 创建 restapi/serializers.py 文件
from rest_framework import serializers from restapi.models import User class UserModelSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('id', 'name', 'email', 'comments', 'created')
5) 修改 restapi/views.py 文件
from django.http import JsonResponse from rest_framework import generics, status from rest_framework.response import Response from restapi.models import User from restapi.serializers import UserModelSerializer def demo(request): data = {'key': 'value'} return JsonResponse(data) class Test(generics.RetrieveAPIView): def retrieve(self, request, *args, **kwargs): data = {'key2': 'value2'} return Response(data, status=status.HTTP_200_OK) class UserList(generics.ListCreateAPIView): queryset = User.objects.all() serializer_class = UserModelSerializer
6) 修改 restapi/urls.py 文件
from django.urls import path, include from restapi import views urlpatterns = [ path('demo/', views.demo), path('demo2/', views.Test.as_view()), path('demo3/', views.UserList.as_view(), name='user_list'), ]
7) 运行
# 创建数据库迁移文件,文件生成在 restapi/migrations 目录下
D:\pipenv_djangodemo\djangoRestDemo> pipenv run python manage.py makemigrations
# 执行数据库迁移文件,创建 MySQL 表,并把迁移记录添加到 'django_migrations' 表
D:\pipenv_djangodemo\djangoRestDemo> pipenv run python manage.py migrate
# 创建 django 管理员用户
D:\pipenv_djangodemo\djangoRestDemo> pipenv run python manage.py createsuperuser
Username (leave blank to use 'admin'): Email address: Password: Password (again): This password is too short. It must contain at least 8 characters. This password is too common. This password is entirely numeric. Bypass password validation and create user anyway? [y/N]: y Superuser created successfully.
注:我们这里设置了用户名是 admin,密码是 123456 。
# 启动 django
D:\pipenv_djangodemo\djangoRestDemo> pipenv run python manage.py runserver
...
访问 http://127.0.0.1:8000/v1/demo3/,显示 User List 的 Rest API 管理页面。
访问 http://127.0.0.1:8000/admin/,输入上面的用户名和密码,登录 django 默认的后台管理页面。
6. Django 命令工具
Django 的 manager.py 提供了命令工具,可以让我们在命令行中测试 Python 代码、读取数据库表数据等。我们继续在上文 djangoRestDemo 项目基础上,演示 Django 命令工具。
1) Shell 命令
进入 Django shell 环境,可以运行如下命令:
D:\pipenv_djangodemo\djangoRestDemo> pipenv run python manage.py shell Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from restapi.models import User >>> list(User.objects.values()) [{'id': 1, 'name': 'Tester', 'email': 'tester@123.com', 'comments': 'Test user', 'created': datetime.datetime(2024, 9, 2, 11, 18, 51, 517975, tzinfo=datetime.timezone.utc)}] >>> exit() # 退出 shell
注:进入交互式命令行下,我们使用上文 restapi/views.py 文件里类似的代码访问数据库表里的数据。
2) dbshell 命令
进入 Django dbshell 环境,可以运行如下命令:
D:\pipenv_djangodemo\djangoRestDemo> pipenv run python manage.py dbshell Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 45 Server version: 10.4.21-MariaDB mariadb.org binary distribution Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [restdemo]> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | restdemo | +--------------------+ 4 rows in set (0.001 sec) MariaDB [restdemo]>
注:MariaDB 是 MySQL 的一个分支。使用 dbshell 需要确保主机环境里有 mysql 命令,mysql 命令一般包含在 MySQL 客户端工具和 MySQL 服务器里。
dbshell 其实是调用 mysql 命令,dbshell 读取了 djangoRestDemo/settings.py 文件里数据库配置信息。
3) 自定义命令
在 djangoRestDemo 项目 restapi 目录下 (项目的已注册 app 目录下都可以),创建 management/commands/ 两级目录,Django 会把 commands 目录下符合自定义命令规范的文件加载到命令管理清单。
创建 restapi/management/commands/TestCmd.py 文件,内容如下:
from django.core.management.base import BaseCommand class Command(BaseCommand): help = 'Test management command' def handle(self, *args, **options): print('TestCmd -> handle()')
运行如下命令:
D:\pipenv_djangodemo\djangoRestDemo> pipenv run python manage.py TestCmd
TestCmd -> handle()
D:\pipenv_djangodemo\djangoRestDemo> pipenv run python manage.py TestCmd -h
usage: manage.py TestCmd [-h] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] [--skip-checks] Test management command optional arguments: -h, --help show this help message and exit --version Show program's version number and exit. -v {0,1,2,3}, --verbosity {0,1,2,3} Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output --settings SETTINGS The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used. --pythonpath PYTHONPATH A directory to add to the Python path, e.g. "/home/djangoprojects/myproject". --traceback Raise on CommandError exceptions. --no-color Don't colorize the command output. --force-color Force colorization of the command output. --skip-checks Skip system checks.
D:\pipenv_djangodemo\djangoRestDemo> pipenv run python manage.py help
Type 'manage.py help <subcommand>' for help on a specific subcommand. Available subcommands: ... [restapi] TestCmd ...