Джанго - от новичка до подмастерья за 2 недели

Django

Знакомство с Джанго

В предыдущем фреймворке для внутренней разработки 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функция, но некоторые системные переменные настроены.

Например, создайте файл с именемmysiteApp , то вы сможете:

# 创建一个 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 сам по себе является мощным и очень зрелым фреймворком для веб-разработки, но с ним сложно начать: нужно много работать, чтобы переварить официальные документы, прочитать исходный код и применить их в своих проектах.

Позже я продолжу делиться некоторым опытом и навыками в процессе разработки этого проекта, пожалуйста, продолжайте обращать внимание! Приватный чат и группа.

Ссылаться на

www.djangoproject.com/