Пять любимых пакетов Django от редакции Pythonist

Одним из самых больших преимуществ Django является его экосистема. Если вы столкнетесь с проблемой, скорее всего, она уже возникала у кого-то из членов сообщества. И этот кто-то был достаточно любезен, чтобы преобразовать ее в пакет и выпустить. Сегодня мы бы хотели рассказать о пяти любимых пакетах Django редакции Pythonist.

Лого сообщества django

1) django-polymorphic

В объектно-ориентированном программировании мы используем термин «полиморфизм» для обозначения объектов, которые имеют общий интерфейс, но не реализацию. Распространенный пример для новичков – моделирование животных в объектно-ориентированном коде. Возьмем собаку и кошку. Они могут издавать звук, который может быть вызван одной и той же функцией, но звук у них будет разный. Более практичный пример – товары в магазине электроники. Они имеют одни и те же характеристики, но во многих других показателях различны.

В каких случаях нам понадобится django-polymorphic? Он упрощает моделирование конкретного многотабличного наследования. Давайте определим несколько абстрактных моделей Project:

from polymorphic.models import PolymorphicModel

class Project(PolymorphicModel):
    topic = models.CharField(max_length=30)

class ArtProject(Project):
    artist = models.CharField(max_length=30)

class ResearchProject(Project):
    supervisor = models.CharField(max_length=30)

Далее мы создадим несколько проектов:

>>> Project.objects.create(topic="Department Party")
>>> ArtProject.objects.create(topic="Painting with Tim", artist="T. Turner")
>>> ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter")

Если мы запросим Project, мы получим полиморфные результаты:

>>> Project.objects.all()
[ <Project:         id 1, topic "Department Party">,
  <ArtProject:      id 2, topic "Painting with Tim", artist "T. Turner">,
  <ResearchProject: id 3, topic "Swallow Aerodynamics", supervisor "Dr. Winter"> ]

2) django-allauth

django-allauth предоставляет из себя набор модульных, хорошо интегрированных приложений, которые позволяют использовать любой из общих потоков регистрации и входа в систему. Таким образом, он отлично подходит для одновременной поддержки как локального, так и социального входа. К тому же он достаточно просто работает.

[python_ad_block]

3) Django Lifecycle Hooks

А вот Django Lifecycle Hooks — наш персональный любимчик. Он все еще находится в стадии бета-тестирования, поэтому мы не очень хотим рекомендовать его для использования в производственной среде. Тем не менее, нам кажется, что он может повысить удобочитаемость и поддержку толстых моделей. Он может заменить как Signals, так и хуки __init__ и save.

Например, если вы привыкли делать с хуками моделей следующее:

class Article(LifecycleModel):
	contents = models.TextField()
	updated_at = models.DateTimeField(null=True)
	status = models.ChoiceField(choices=['draft', 'published'])
	editor = models.ForeignKey(AuthUser)

	def __init__(self, *args, **kwargs):
    	super().__init__(*args, **kwargs)
    	self._orig_contents = self.contents
    	self._orig_status = self.status


	def save(self, *args, **kwargs):
    	if self.pk is not None and self.contents != self._orig_contents):
        	self.updated_at = timezone.now()

    	super().save(*args, **kwargs)

    	if self.status != self._orig_status:
        	send_email(self.editor.email, "An article has published!")

То теперь вы можете делать так:

from django_lifecycle import LifecycleModel, hook, BEFORE_UPDATE, AFTER_UPDATE


class Article(LifecycleModel):
	contents = models.TextField()
	updated_at = models.DateTimeField(null=True)
	status = models.ChoiceField(choices=['draft', 'published'])
	editor = models.ForeignKey(AuthUser)

	@hook(BEFORE_UPDATE, when='contents', has_changed=True)
	def on_content_change(self):
    	self.updated_at = timezone.now()

	@hook(AFTER_UPDATE, when="status", was="draft", is_now="published")
	def on_publish(self):
    	send_email(self.editor.email, "An article has published!")

Хуки также могут ссылаться на изменения полей связанного объекта (например, внешнего ключа). Опять же, важно отметить, что этот пакет находится в стадии бета-тестирования. Поэтому тестирование и просмотр необработанного SQL крайне важны.

4) Django Extensions

Django Extensions, пожалуй, один из старейших пакетов Django. Он заслуживает отдельной статьи. Однако вот несколько функций, которые полезно знать:

shell_plus

./manage.py shell_plus

Указанная выше команда запустит оболочку Django с моделями всех ваших приложений, импортированными и готовыми к использованию. Нам нравится комбинировать его с IPython для лучшего автозаполнения.

RunScript

Иногда необходимо запустить скрипт в  приложении Django. Обычно в процессе написания своего скрипта используется оболочка Django для управления разработкой. Затем всё оборачивается в Django-команду. Однако с помощью команды RunScript вы сможете запустить скрипт напрямую, заключив его в простую функцию. Например, если вы хотите написать скрипт для удаления всех объектов Question в вашей базе данных, это будет очень просто:

from polls.models import Question

def run():
	# Fetch all questions
	questions = Question.objects.all()
	# Delete questions
	questions.delete()

А дальше, чтобы запустить скрипт, выполните следующую команду:

./manage.py manage.py runscript  delete_all_questions

syncdata

Эта функция сбросит вашу базу данных таким образом, что она будет содержать только указанные вами фикстуры. Именно так, как вы указали их в фикстур-файле.

graph_models

Данная команда построит графики моделей ваших приложений. Это позволит вам увидеть лежащие в основе отношения, аналогичные ER-модели.

5) Cookiecutter Django

Если вы настраивали проект Django раньше, вы знаете, что django-admin startproject mysite не подходит для разработки современных веб-приложений. В нем нет таких наворотов, как переменные среды для конфигурации, интеграция с Postgres из коробки, установка Docker (подробнее о конфигурации Django Docker при развертывании приложений можно узнать тут) и т. д. Однако, об этом всем позаботится Django Cookiecutter.

Мы рекомендуем использовать его после того, как вы ознакомитесь с каждым компонентом, который планируете использовать, по отдельности. Иначе количество магии и принятых за вас решений помешает вам отлаживать приложение в будущем. Более того, это также может привести к появлению большого количества мертвого кода в вашей кодовой базе. Так что, если вы не знаете, что для чего используется, будьте предельно осторожны!

Заключение

В данной статье мы рассказали о пяти любимых пакетах Django от редакции Pythonist, разобрали их особенности и тонкости применения.