Знакомство с Джанго
В предыдущем фреймворке для внутренней разработки Python больше контактировали с Tornado и Flask, первый подходит в качестве сервисного фреймворка, а второй обычно используется для создания простых бэкендов или сервисов из-за его небольшого веса.
По сравнению с двумя вышеперечисленными веб-фреймворками, Django сам реализует множество библиотек классов инструментов, что более громоздко, но после начала работы многие функции не нужно реализовывать самостоятельно, что более удобно.
Django также чаще используется в качестве среды разработки бэкэнда из-за множества интегрированных функций.
Недавно я взял на себя задачу фоновой разработки, основанную на разработке Django, поэтому эта статья обобщает то, что я узнал за последние две недели.
Использование модуля Джанго
Прежде чем подробно рассказать о коде, позвольте мне рассказать об архитектуре всей системы.
Когда я впервые взялся за эту задачу, база данных использовала MySQL 5.5, а соответствующая версия Django была 2.0 (самая высокая версия, поддерживающая MySQL 5.5).
Учитывая, что система подключена к разным продуктовым линейкам, а некоторые форматы данных неопределенны, я поменял базу данных на MySQL 5.7 с поддержкой формата JSON, а также Django обновился до последней версии 2.2. Конечно, можно использовать и другие базы данных, такие как PostgreSQL или MongoDB.Чтобы не влиять на операционные привычки первоначальных разработчиков, я все еще продолжаю использовать MySQL.
В то же время, учитывая трудоемкость операции загрузки и анализа файлов Excel на платформе, я представил Celery + RabbitMQ для реализации асинхронного выполнения таких операций и оптимизации взаимодействия с пользователем.
В Django по-прежнему есть много функций, которые я еще не использовал.Его мощные функции действительно сократили количество кода, который мне нужно построить для создания колес, но, будучи новичком, я действительно тратил много времени на размышления о каждой функции.
Давайте поговорим о нескольких модулях Django и их основном использовании, которые были затронуты за последние две недели.Более подробные функции можно найти в официальной документации.
manage.py
Прежде чем мы официально поговорим о функциональных модулях, мы должны сначала представить мощные инструменты управления проектами, которые поставляются с Django:django-admin
.
Обычно мы создаем проект Django следующим образом:
# 安装 Django
pip install django
# 创建一个 Django 项目
django-admin startproject myproject
После создания проекта Django корневой путь проекта сгенерируетmanage.py
документ. Что на самом деле делает файлdjango-admin
функция, но некоторые системные переменные настроены.
Например, создайте файл с именемmysite
App , то вы сможете:
# 创建一个 App
python manage.py startapp mysite
Запомните этот mysite , это имя вашего приложения, а не просто имя папки, и последующий код разработки будет точно ссылаться на это имя.
использоватьmanage.py
Инструмент управления может легко реализовать такие операции, как запуск службы, миграция базы данных и т. д. В частности, миграция базы данных — это моя наиболее часто используемая и любимая функция, о которой будет сказано позже.
Проекты и приложения
В Джанго естьProject
(предмет) сApp
(приложение), которое отличается следующим:
Project
является высшим уровнем всего проекта и находится вProject
Настройте зависимости, среду и т. д., необходимые для проекта;
App
В зависимости от проекта проект может иметь несколько приложений.
Вообще говоря, отдельный фоновый проект управленияНастроить приложениеТо есть разные пользователи, проекты, задачи и другие функции относятся к одному и тому жеApp
. И если нам нужно разработать внутренний управленческий фон для интеграции 2-х разных систем, в каждой из которых есть такие модули, как проекты и задачи, то мы создаем 2App
, потому что функции в двух приложениях не связаны друг с другом.
Model
Django может использовать модель ORM (Object Relational Mapping) для работы с базой данных, например:
# 获取当前用户的用户名
operator = request.user
return operator.username
Простые две строки кода, нижний уровень был реализован Django для подключения к базе данных (пул соединений), запроса пользовательской таблицы, возврата значения поля имени пользователя и других функций.
Я до сих пор помню, что когда я использовал Tornado для написания сервиса, мне нужно было самому поддерживать синглтон базы данных, заботиться о последовательности инициализации экземпляра базы данных при запуске сервиса и т. д.
Использование ORM требует от вас созданияModel
, который содержит ваше определение полей таблицы, таких как типы полей, значения по умолчанию, ограничения внешнего ключа и т. д.
Например,Task
Модель стола:
models.py
class Task(models.Model):
status = models.IntegerField(default=0)
assignee = models.ForeignKey(settings.AUTH_USER_MODEL,
related_name='+',
null=True,
on_delete=models.SET_NULL)
create_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
Здесь также есть моменты, на которые следует обратить внимание: если специально не настроено, имя класса Model будет использоваться как часть имени таблицы базы данных, полное: mysite_task
.
Migration
После создания модели таблицы базы данных мы можем использовать функцию миграции для создания сценария инициализации таблицы и фактического создания таблицы в базе данных:
# 初始化迁移脚本
python manage.py makemigrations [<APP_NAME>]
# 执行迁移操作,将数据库脚本在对应的数据库中执行一遍
python manage.py migrate
Сила миграции заключается в том, что когда вам нужно обновить поле (например, установить значение по умолчанию для поля), вы можете напрямую изменить конфигурацию поля в модели, а затем выполнить ее снова.makemigrations
, Django создаст новый сценарий базы данных, чтобы вы могли записать обновление, а затем выполнитьmigrate
Затем обновление записывается в базу данных.
Мало того, мы также можем создать пустой скрипт миграции для записи операций вставки данных. С помощью этого скрипта мы можем сохранить часть тестовых данных при переносе системы:
from django.db import migrations
# 插入方法
def insert_task(apps, schema_editor):
Task = apps.get_model('mysite', "Task")
db_alias = schema_editor.connection.alias
Task.objects.using(db_alias).bulk_create([
Task(name='task1'),
])
# 回滚方法
def rollback_task(apps, schema_editor):
Task = apps.get_model('mysite', "Task")
db_alias = schema_editor.connection.alias
Task.objects.using(db_alias).filter(name="task1").delete()
class Migration(migrations.Migration):
dependencies = [
('mysite', '0001_initial'),
]
operations = [
migrations.RunPython(insert_task, rollback_task),
]
Для каждой миграции Django будет вести запись, которая может определить операции, которые были выполнены, операции, которые необходимо выполнить, и операции, которые являются рискованными. можно использоватьshowmigrations
Проверьте выполнение скриптов миграции БД для каждого приложения:
python manage.py showmigrations
View
Django — это режим MVT, View эквивалентен Controller (контроллеру), а не View (представлению) в режиме проектирования MVC. Реальный вид обеспечивается шаблоном или статическими ресурсами.
Поскольку это контроллер, функция представления относительно ясна: полученные данные запроса (запрос) обрабатываются соответствующим образом, а данные результата обработки (ответ) возвращаются.
Представление может быть классом, а может быть функцией + режим декоратора представления, переходим непосредственно к коду официального документа:
Представление на основе классов:
from django.http import HttpResponse
from django.views.generic import ListView
from books.models import Book
class BookListView(ListView):
model = Book
def head(self, *args, **kwargs):
last_book = self.get_queryset().latest('publication_date')
response = HttpResponse('')
# RFC 1123 date format
response['Last-Modified'] = last_book.publication_date.strftime('%a, %d %b %Y %H:%M:%S GMT')
return response
Представление на основе декоратора:
from django.views.decorators.http import require_http_methods
@require_http_methods(["GET", "POST"])
def my_view(request):
# I can assume now that only GET or POST requests make it this far
# ...
pass
Эта часть больше связана с бизнес-логикой и не является достаточно общей, поэтому я не буду вдаваться в подробности.
URL
Модуль URL определяет адрес маршрутизации представления:
mysite/urls.py
from django.urls import path
from books.views import BookListView
urlpatterns = [
path('books/', BookListView.as_view()),
]
Можно настроить несколько уровней маршрутизации, а затем использовать их в URL-адресе верхнего уровня.includes
Добавьте префикс к подмаршруту:
myproject/urls.py
path('api/v1/', include('mysite.urls')),
Test
Как инженер-разработчик тестов, вам все еще необходимо понимать модуль модульного тестирования (к сожалению, в настоящее время он находится на ранней стадии разработки, и, возможно, потребуется добавить тестовые случаи после того, как проект станет в основном стабильным).
Как и большинство веб-фреймворков, тестовый модуль Django также предоставляет HTTP-клиент для «модульного тестирования» с использованием шаблона, аналогичного тестированию интерфейса.
Когда я писал базовую структуру модульного тестирования Tornado, я издевался над соединением между Tornado и базой данных, но на самом деле не работал с базой данных. Но в Django, поскольку подключение к базе данных мной не реализовано, и поскольку используется режим ORM, трудно реально отделиться от других сервисов для одиночного тестирования, поэтому я пока оставлю этот режим тестирования.
Или возьмите официальный образец код в качестве примера, напишите класс для тестирования:
import unittest
from django.test import Client
class SimpleTest(unittest.TestCase):
def setUp(self):
# Every test needs a client.
self.client = Client()
def test_details(self):
# Issue a GET request.
response = self.client.get('/customer/details/')
# Check that the response is 200 OK.
self.assertEqual(response.status_code, 200)
# Check that the rendered context contains 5 customers.
self.assertEqual(len(response.context['customers']), 5)
Запустите модульные тесты:
python manage.py test
Структура каталогов кода
Когда я взялся за проект, большая часть кода была объединена в один файл Python, что делало его очень неудобным для людей, следящих за чистотой кода.
Поскольку я только сам соприкасался с Django, я также наступил на множество ям для математической структуры каталогов, включая разделение каждого модуля на разные приложения и другие хитрые операции...
Я просто поделюсь грубой структурой кода, которую я сейчас использую:
myapp/ # 存放应用具体实现的代码等
app_mod1/
models.py
views.py
app_mod2/
models.py
views.py
admin.py
app.py
models.py
views.py
urls.py
myproject/ # 存放项目配置文件
settings.py
urls.py
dockerfiles/ # 存放前后端Dockerfile
docs/ # 存放项目相关的文档
tests/ # 存放测试套件
manage.py
README.md
Суммировать
В этом проекте я также представил модули сериализации и подкачки фреймворка Django-REST-Framework (DRF), поддержку Django-MySQL для данных в формате JSON/List и реализацию асинхронных и синхронизированных задач в Celery. Я доволен изучением Django и модулей расширения, но за этим стоит тяжелая работа, из-за которой я продолжаю работать до 11 часов каждый день после окончания работы, а по выходным проверяю документы и занимаюсь дома.
Django сам по себе является мощным и очень зрелым фреймворком для веб-разработки, но с ним сложно начать: нужно много работать, чтобы переварить официальные документы, прочитать исходный код и применить их в своих проектах.
Позже я продолжу делиться некоторым опытом и навыками в процессе разработки этого проекта, пожалуйста, продолжайте обращать внимание! Приватный чат и группа.