How to add/Migrate SQLite to PostGres SQL in your Django project
To add PostgreSQL as the database backend for your Django project, you'll need to follow these steps:
Step 1: Install the Required Packages Make sure you have the necessary packages installed. You'll need psycopg2, which is the PostgreSQL adapter for...
Read: https://ifiokambrose.hashnode.dev/how-to-addmigrate-sqlite-to-postgres-sql-in-your-django-project
To add PostgreSQL as the database backend for your Django project, you'll need to follow these steps:
Step 1: Install the Required Packages Make sure you have the necessary packages installed. You'll need psycopg2, which is the PostgreSQL adapter for...
Read: https://ifiokambrose.hashnode.dev/how-to-addmigrate-sqlite-to-postgres-sql-in-your-django-project
Get and Post methods using Flask, Django, and FastAPI
HTTP provides different methods for communication between a client and a server. In the article, we're going to decode the basics of get and post methods using various Python frameworks.
Introduction
HTTP methods, also known as HTTP verbs, are an in...
Read: https://therareblogle.hashnode.dev/get-and-post-methods-using-flask-django-and-fastapi
HTTP provides different methods for communication between a client and a server. In the article, we're going to decode the basics of get and post methods using various Python frameworks.
Introduction
HTTP methods, also known as HTTP verbs, are an in...
Read: https://therareblogle.hashnode.dev/get-and-post-methods-using-flask-django-and-fastapi
PyCharm & DSF Campaign 2023
The Django Software Foundation’s biggest fundraising event of the year is here!
https://www.jetbrains.com/pycharm/promo/support-django/
Each year, our friends at JetBrains, the creators of PyCharm, run an incredible deal. You get a 30% discounted year of PyCharm, AND the DSF gets 100% of the proceeds. Plus, get one free month of access to JetBrains Academy, which has courses like Intro to Django, SQL, Git, and more!
The fundraiser runs from July 3rd-July 23rd! Buy PyCharm and support Django!
Donations like this fundraiser allow the DSF to function. Our two wonderful Fellows, Mariusz Felisiak and Natalia Bidart keep Django running smoothly. In 2022, our Fellows (Carlton Gibson and Mariusz) were instrumental in:
* Releasing 25 Django versions, including 4.1 and the preparation for 4.2
* Maintaining security: 10 CVEs were identified and patched in a timely manner
* Triaging hundreds of new issues
* Managing and supporting the community through mailing lists and forums
In the past, JetBrains through the PyCharm fundraiser has provided approximately one quarter of the Django Software Foundation’s budget! Remember, get your discounted year of PyCharm now, and the DSF will receive 100% of proceeds!
The other side of the DSF is our support for Django groups across the globe. We have supported each of the DjangoCons held across the globe, particularly with donating funding towards opportunity grants for more people to be able to attend these conferences. The DSF also supports smaller events around the world, including DjangoGirls events.
2023 is off to a great start where we hope to do more with your help!
Finally, I want to tell you about PyCharm itself.
PyCharm is an integrated development environment (IDE) that helps professional Python web developers be more productive, be more confident, and write better code. It supports the full Python web workflow out of the box, including popular Python web frameworks, such as Django, frontend technologies, and databases.
Here are the main benefits of using PyCharm in your Django development:
* The built-in Django run/debug configuration type makes it easy to configure and start the Django server.
* Syntax and error highlighting, code completion, navigation between views and templates, ability to debug templates visually by inserting a breakpoint right in the editor.
* Special coding assistance within standard files: urls.py and settings.py: files, folders, view methods, regex injection and highlighting. Utilize intentions to let PyCharm create views and templates from usage.
* Autocompletion for static resource names in templates, special interactive task window for manage.py with project-driven autocomplete, Jinja and Mako templates in Django, code intentions such as convert function view to/from class-based view, template inspections to warn for mistakes, i18n helpers, live templates for Django, model diagrams, and more.
Get Django work done with PyCharm, a powerful IDE tailored for Django web development!
Consider this the easiest charitable donation you will ever make, when you get such a great product in return!
If you would like to donate in another way, especially if you are already a PyCharm customer, here are other ways to donate to the DSF:
On our website via credit card: https://www.djangoproject.com/fundraising/
Via GitHub sponsors: https://github.com/sponsors/django
For those able to make a larger donation, particularly corporate sponsors, more information: https://www.djangoproject.com/foundation/corporate-membership/ and application: https://www.djangoproject.com/foundation/corporate-membership/join/
Thank you,
Catherine Holmes
DSF Assistant
Read: https://www.djangoproject.com/weblog/2023/jul/03/pycharm-dsf-campaign-2023/
The Django Software Foundation’s biggest fundraising event of the year is here!
https://www.jetbrains.com/pycharm/promo/support-django/
Each year, our friends at JetBrains, the creators of PyCharm, run an incredible deal. You get a 30% discounted year of PyCharm, AND the DSF gets 100% of the proceeds. Plus, get one free month of access to JetBrains Academy, which has courses like Intro to Django, SQL, Git, and more!
The fundraiser runs from July 3rd-July 23rd! Buy PyCharm and support Django!
Donations like this fundraiser allow the DSF to function. Our two wonderful Fellows, Mariusz Felisiak and Natalia Bidart keep Django running smoothly. In 2022, our Fellows (Carlton Gibson and Mariusz) were instrumental in:
* Releasing 25 Django versions, including 4.1 and the preparation for 4.2
* Maintaining security: 10 CVEs were identified and patched in a timely manner
* Triaging hundreds of new issues
* Managing and supporting the community through mailing lists and forums
In the past, JetBrains through the PyCharm fundraiser has provided approximately one quarter of the Django Software Foundation’s budget! Remember, get your discounted year of PyCharm now, and the DSF will receive 100% of proceeds!
The other side of the DSF is our support for Django groups across the globe. We have supported each of the DjangoCons held across the globe, particularly with donating funding towards opportunity grants for more people to be able to attend these conferences. The DSF also supports smaller events around the world, including DjangoGirls events.
2023 is off to a great start where we hope to do more with your help!
Finally, I want to tell you about PyCharm itself.
PyCharm is an integrated development environment (IDE) that helps professional Python web developers be more productive, be more confident, and write better code. It supports the full Python web workflow out of the box, including popular Python web frameworks, such as Django, frontend technologies, and databases.
Here are the main benefits of using PyCharm in your Django development:
* The built-in Django run/debug configuration type makes it easy to configure and start the Django server.
* Syntax and error highlighting, code completion, navigation between views and templates, ability to debug templates visually by inserting a breakpoint right in the editor.
* Special coding assistance within standard files: urls.py and settings.py: files, folders, view methods, regex injection and highlighting. Utilize intentions to let PyCharm create views and templates from usage.
* Autocompletion for static resource names in templates, special interactive task window for manage.py with project-driven autocomplete, Jinja and Mako templates in Django, code intentions such as convert function view to/from class-based view, template inspections to warn for mistakes, i18n helpers, live templates for Django, model diagrams, and more.
Get Django work done with PyCharm, a powerful IDE tailored for Django web development!
Consider this the easiest charitable donation you will ever make, when you get such a great product in return!
If you would like to donate in another way, especially if you are already a PyCharm customer, here are other ways to donate to the DSF:
On our website via credit card: https://www.djangoproject.com/fundraising/
Via GitHub sponsors: https://github.com/sponsors/django
For those able to make a larger donation, particularly corporate sponsors, more information: https://www.djangoproject.com/foundation/corporate-membership/ and application: https://www.djangoproject.com/foundation/corporate-membership/join/
Thank you,
Catherine Holmes
DSF Assistant
Read: https://www.djangoproject.com/weblog/2023/jul/03/pycharm-dsf-campaign-2023/
Advanced Django Cheat Sheet
This article was originally posted to my personal blog
Be aware it's not an exhaustive list.
If you have ideas, correction or recommendation do not hesitate and do so on Github or in the comments section.
Sections
Preparing environnement
Creating a...
Read: https://julienc.hashnode.dev/advanced-django-cheat-sheet
This article was originally posted to my personal blog
Be aware it's not an exhaustive list.
If you have ideas, correction or recommendation do not hesitate and do so on Github or in the comments section.
Sections
Preparing environnement
Creating a...
Read: https://julienc.hashnode.dev/advanced-django-cheat-sheet
How to integrate stripe to Django
Step 1: Install the required packages
Ensure that you have the necessary packages installed. You can use pip to install them:
pip install stripe
pip install djstripe
Step 2: Configure Django settings
Open your Django project's settings file (setting...
Read: https://ifiokambrose.hashnode.dev/how-to-integrate-stripe-to-django
Step 1: Install the required packages
Ensure that you have the necessary packages installed. You can use pip to install them:
pip install stripe
pip install djstripe
Step 2: Configure Django settings
Open your Django project's settings file (setting...
Read: https://ifiokambrose.hashnode.dev/how-to-integrate-stripe-to-django
Road-Map for Python Developers
Should I learn Python? Some weeks ago, someone asked me if Python is good for beginners.
I ponder the questions above and figured many people still have no idea what programming language to use.
The fact that new evolving languages constantly bomba...
Read: https://learnhubafrica.hashnode.dev/road-map-for-python-developers
Should I learn Python? Some weeks ago, someone asked me if Python is good for beginners.
I ponder the questions above and figured many people still have no idea what programming language to use.
The fact that new evolving languages constantly bomba...
Read: https://learnhubafrica.hashnode.dev/road-map-for-python-developers
DJANGO-sign in page with OTP verification via email
While learning a framework ,creating mini projects helps us to explore the features of the framework.Now,we are going to create a simple sign-in page with email verification using Django.At the end of this blog,you will get an insight about the djang...
Read: https://pythongeek.hashnode.dev/django-sign-in-page-with-otp-verification-via-email
While learning a framework ,creating mini projects helps us to explore the features of the framework.Now,we are going to create a simple sign-in page with email verification using Django.At the end of this blog,you will get an insight about the djang...
Read: https://pythongeek.hashnode.dev/django-sign-in-page-with-otp-verification-via-email
👍1
Django-Dynamic HTML page creation with image(user profile page )
In this blog,we are going to create a log-in page for our page and we will create a dynamic html page for displaying user’s profile and personal details whoever logs in.Displaying user uploaded images inside an app along with user details is explaine...
Read: https://pythongeek.hashnode.dev/django-dynamic-html-page-creation-with-imageuser-profile-page
In this blog,we are going to create a log-in page for our page and we will create a dynamic html page for displaying user’s profile and personal details whoever logs in.Displaying user uploaded images inside an app along with user details is explaine...
Read: https://pythongeek.hashnode.dev/django-dynamic-html-page-creation-with-imageuser-profile-page
Creating Open-Source Resources for The Community (Ep 2)
Mastori, as the name implies, is a platform where community members can share their blogs and articles. The name "Mastori" originates from Kenyan slang, sheng, meaning "many stories." Our vision is to provide a space for individuals to write about to...
Read: https://spaceyatech.hashnode.dev/creating-open-source-resources-for-the-community-ep-2
Mastori, as the name implies, is a platform where community members can share their blogs and articles. The name "Mastori" originates from Kenyan slang, sheng, meaning "many stories." Our vision is to provide a space for individuals to write about to...
Read: https://spaceyatech.hashnode.dev/creating-open-source-resources-for-the-community-ep-2
Mastering Django CI/CD using GitHub Actions
Testing and delivery is a common repetitive cycle in application development. This cycle consumes more time and resources as we fix or add more features to our application. Automating this repetitive process will reduce the time spent in application ...
Read: https://thecodeway.hashnode.dev/mastering-django-cicd-using-github-actions
Testing and delivery is a common repetitive cycle in application development. This cycle consumes more time and resources as we fix or add more features to our application. Automating this repetitive process will reduce the time spent in application ...
Read: https://thecodeway.hashnode.dev/mastering-django-cicd-using-github-actions
Django Unleashed Framework
Photo
Интеграция Django с материализованными представлениями PostgreSQL
Django — один из самых популярных веб-фреймворков, написанных на Python. Он следует принципу “Не повторяйся” (DRY) и быстро решает задачи веб-разработки с помощью набора инструментов, библиотек и соглашений.
Действительно продвинутым Django делает встроенная поддержка ORM (механизма объектно-реляционного отображения), который разрабатывает команда Django. Модель данных в Django представлена в виде классов Python, в которых можно создавать и запрашивать таблицы базы данных без использования необработанных SQL-запросов.
В этой статье мы рассмотрим, как интегрировать Django с материализованными представлениями PostgreSQL. Настроим ORM Django на полную поддержку материализованных представлений, определив модели материализованных представлений в проекте Django таким образом, чтобы изменения модели могли быть обнаружены системой миграции Django.
Что такое материализованные представления?
Представления в движках баз данных — это виртуальные таблицы, предоставляющие возможность выполнять запросы и получать данные из существующих таблиц. Они позволяют упростить процесс выполнения сложных запросов. Однако использование представлений, динамически выполняющих первичный запрос (primary query) при каждом обращении, может идти в ущерб производительности.
Именно здесь в игру вступают материализованные представления. В отличие от обычных, материализованные представления хранят результаты базового запроса в физической таблице. Другими словами, материализованные представления компилируют результаты запроса и сохраняют их как отдельную сущность в базе данных. Поэтому получить доступ к материализованным представлениям можно намного быстрее, чем к обычным представлениям, предполагающим повторное выполнение запроса при каждом обращении.
При этом необходимо учитывать некоторые недостатки материализованных представлений.
1. Данные в материализованных представлениях могут устаревать, если не обновлять их регулярно, что может привести к несоответствиям.
2. Необходимо учитывать требования к хранению, поскольку материализованные представления потребляют дисковое пространство для хранения данных.
3. Материализованные представления добавляют сложности системе, так как требуют обслуживания при обновлении базовых таблиц.
Создание материализованного представления в PostgreSQL
Материализованное представление можно создать с помощью следующей команды SQL:
CREATE MATERIALIZED VIEW popular_posts AS
SELECT * FROM posts WHERE rating > 200;
Этот запрос создаст новое материализованное представление из базового запроса с кэшированным результатом. При этом обновленные данные в исходной таблице не будут автоматически доступны в материализованном представлении, так как их нужно будет обновить вручную с помощью следующей команды:
REFRESH MATERIALIZED VIEW popular_posts;
Эта команда обновит материализованное представление и заполнит свежими данными базовую таблицу, а также перекомпилирует определение базового запроса материализованного представления.
Проблема
Поскольку в настоящее время ORM Django поддерживает только таблицы баз данных, мне стало интересно, можно ли настроить ORM Django для поддержки материализованных представлений. Проведя исследование, я понял, что можно добиться этого несколькими способами, но не был удовлетворен ни одним решением, так как ни одна из настроек не могла полностью поддерживать материализованные представления для использования в качестве моделей Django.
Одно из решений предполагало создание пустого файла миграции вручную и указание SQL-запроса для создания материализованного представления с помощью команды
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("api", "0001_initial"),
]
operations = [
migrations.RunSQL(
sql="CREATE MATERIALIZED VIEW popular_posts AS SELECT * FROM posts WHERE rating > 200",
reverse_sql="DROP MATERIALIZED VIEW popular_posts"
)
]
Кроме того, нео[...]
Django — один из самых популярных веб-фреймворков, написанных на Python. Он следует принципу “Не повторяйся” (DRY) и быстро решает задачи веб-разработки с помощью набора инструментов, библиотек и соглашений.
Действительно продвинутым Django делает встроенная поддержка ORM (механизма объектно-реляционного отображения), который разрабатывает команда Django. Модель данных в Django представлена в виде классов Python, в которых можно создавать и запрашивать таблицы базы данных без использования необработанных SQL-запросов.
В этой статье мы рассмотрим, как интегрировать Django с материализованными представлениями PostgreSQL. Настроим ORM Django на полную поддержку материализованных представлений, определив модели материализованных представлений в проекте Django таким образом, чтобы изменения модели могли быть обнаружены системой миграции Django.
Что такое материализованные представления?
Представления в движках баз данных — это виртуальные таблицы, предоставляющие возможность выполнять запросы и получать данные из существующих таблиц. Они позволяют упростить процесс выполнения сложных запросов. Однако использование представлений, динамически выполняющих первичный запрос (primary query) при каждом обращении, может идти в ущерб производительности.
Именно здесь в игру вступают материализованные представления. В отличие от обычных, материализованные представления хранят результаты базового запроса в физической таблице. Другими словами, материализованные представления компилируют результаты запроса и сохраняют их как отдельную сущность в базе данных. Поэтому получить доступ к материализованным представлениям можно намного быстрее, чем к обычным представлениям, предполагающим повторное выполнение запроса при каждом обращении.
При этом необходимо учитывать некоторые недостатки материализованных представлений.
1. Данные в материализованных представлениях могут устаревать, если не обновлять их регулярно, что может привести к несоответствиям.
2. Необходимо учитывать требования к хранению, поскольку материализованные представления потребляют дисковое пространство для хранения данных.
3. Материализованные представления добавляют сложности системе, так как требуют обслуживания при обновлении базовых таблиц.
Создание материализованного представления в PostgreSQL
Материализованное представление можно создать с помощью следующей команды SQL:
CREATE MATERIALIZED VIEW popular_posts AS
SELECT * FROM posts WHERE rating > 200;
Этот запрос создаст новое материализованное представление из базового запроса с кэшированным результатом. При этом обновленные данные в исходной таблице не будут автоматически доступны в материализованном представлении, так как их нужно будет обновить вручную с помощью следующей команды:
REFRESH MATERIALIZED VIEW popular_posts;
Эта команда обновит материализованное представление и заполнит свежими данными базовую таблицу, а также перекомпилирует определение базового запроса материализованного представления.
Проблема
Поскольку в настоящее время ORM Django поддерживает только таблицы баз данных, мне стало интересно, можно ли настроить ORM Django для поддержки материализованных представлений. Проведя исследование, я понял, что можно добиться этого несколькими способами, но не был удовлетворен ни одним решением, так как ни одна из настроек не могла полностью поддерживать материализованные представления для использования в качестве моделей Django.
Одно из решений предполагало создание пустого файла миграции вручную и указание SQL-запроса для создания материализованного представления с помощью команды
RunSQL
.from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("api", "0001_initial"),
]
operations = [
migrations.RunSQL(
sql="CREATE MATERIALIZED VIEW popular_posts AS SELECT * FROM posts WHERE rating > 200",
reverse_sql="DROP MATERIALIZED VIEW popular_posts"
)
]
Кроме того, нео[...]
❤1
Django Unleashed Framework
Интеграция Django с материализованными представлениями PostgreSQL Django — один из самых популярных веб-фреймворков, написанных на Python. Он следует принципу “Не повторяйся” (DRY) и быстро решает задачи веб-разработки с помощью набора инструментов, библиотек…
бходимо создать класс модели, определив поля точно так же, как и в запросе материализованного представления. Класс модели должен иметь:
* опцию
* опцию
class PopularPosts(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
tag_names = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
rating = models.PositiveIntegerField()
class Meta:
managed = False
db_table = 'popular_posts'
На мой взгляд, данный подход не является оптимальным решением, эффективным в долгосрочной перспективе, особенно при частых обновлениях или изменениях атрибутов класса модели. Когда потребуется изменение атрибутов класса модели, нужно переписывать новый необработанный запрос в новом файле миграции, что может занять много времени и чревато ошибками. Более того, это может стать громоздкой задачей, особенно по мере роста и развития приложения с течением времени.
Как интегрировать Django с материализованными представлениями
Чтобы интегрировать Django с материализованными представлениями, в нашем примере будет применено несколько настроек.
* Создание пользовательского класса модели.
* Создание пользовательского класса поля модели.
* Создание пользовательского движка базы данных для PostgreSQL.
* Соединение всего созданного в проекте.
Шаг 1. Создание пользовательского класса модели
Первым шагом к интеграции Django с материализованными представлениями в PostgreSQL является создание пользовательского класса модели с целью сообщить Django, что модель предназначена для материализованного представления.
Существует несколько способов определить, является ли класс модели материализованным представлением. Я создал класс модели таким образом, чтобы он принимал два пользовательских атрибута класса Meta внутри класса модели.
*
*
class MaterializedViewModel(models.Model):
class Meta:
materialized_view = True
view_parent_model = 'app_label.Model'
Обычно Django не позволяет определять пользовательские атрибуты своего класса Meta внутри классов модели, выдавая исключение TypeError:
raise TypeError(
TypeError: 'class Meta' got invalid attribute(s): materialized_view
Проведя исследование, я обнаружил, что в Django можно использовать только атрибуты Meta, которые статически определены в кортеже
# djangoProject/__init__.py
import django.db.models.options as options
options.DEFAULT_NAMES += ('materialized_view', 'view_parent_model',)
Шаг 2. Создание пользовательского поля модели
Следующий шаг — создание пользовательского поля модели, специально предназначенного для класса модели материализованного представления, которое будет иметь два пользовательских атрибута. Каждое из пользовательских полей, указанных в классе модели, впоследствии будет преобразовано в необработанные SQL-запросы для генерации SQL, что необходимо для создания материализованного представления.
from[...]
* опцию
managed
, которую нужно установить в false в определении мета-класса для указания того, что схема базы данных не должна управляться Django, чтобы предотвратить создание новой таблицы системой миграции;* опцию
db_table
, которая должна быть явно установлена в соответствии с именем материализованного представления.class PopularPosts(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
tag_names = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
rating = models.PositiveIntegerField()
class Meta:
managed = False
db_table = 'popular_posts'
На мой взгляд, данный подход не является оптимальным решением, эффективным в долгосрочной перспективе, особенно при частых обновлениях или изменениях атрибутов класса модели. Когда потребуется изменение атрибутов класса модели, нужно переписывать новый необработанный запрос в новом файле миграции, что может занять много времени и чревато ошибками. Более того, это может стать громоздкой задачей, особенно по мере роста и развития приложения с течением времени.
Как интегрировать Django с материализованными представлениями
Чтобы интегрировать Django с материализованными представлениями, в нашем примере будет применено несколько настроек.
* Создание пользовательского класса модели.
* Создание пользовательского класса поля модели.
* Создание пользовательского движка базы данных для PostgreSQL.
* Соединение всего созданного в проекте.
Шаг 1. Создание пользовательского класса модели
Первым шагом к интеграции Django с материализованными представлениями в PostgreSQL является создание пользовательского класса модели с целью сообщить Django, что модель предназначена для материализованного представления.
Существует несколько способов определить, является ли класс модели материализованным представлением. Я создал класс модели таким образом, чтобы он принимал два пользовательских атрибута класса Meta внутри класса модели.
*
materialized_view
указывает, что класс модели является материализованным представлением, а не таблицей.*
view_parent_model
указывает классу модели, какой реальный класс модели должен использоваться, чтобы создать базовый запрос для материализованного представления.class MaterializedViewModel(models.Model):
class Meta:
materialized_view = True
view_parent_model = 'app_label.Model'
Обычно Django не позволяет определять пользовательские атрибуты своего класса Meta внутри классов модели, выдавая исключение TypeError:
raise TypeError(
TypeError: 'class Meta' got invalid attribute(s): materialized_view
Проведя исследование, я обнаружил, что в Django можно использовать только атрибуты Meta, которые статически определены в кортеже
DEFAULT_NAMES
, который находится в модуле django.db.models.options
. Чтобы устранить это ограничение, я применил обходной путь, импортировав модуль options и переопределив переменную DEFAULT_NAMES
в файле __init__.py
модуля проекта перед наполнением приложений Django. Эта модификация обеспечивает поддержку пользовательских атрибутов в классе Meta.# djangoProject/__init__.py
import django.db.models.options as options
options.DEFAULT_NAMES += ('materialized_view', 'view_parent_model',)
Шаг 2. Создание пользовательского поля модели
Следующий шаг — создание пользовательского поля модели, специально предназначенного для класса модели материализованного представления, которое будет иметь два пользовательских атрибута. Каждое из пользовательских полей, указанных в классе модели, впоследствии будет преобразовано в необработанные SQL-запросы для генерации SQL, что необходимо для создания материализованного представления.
from[...]
Django Unleashed Framework
бходимо создать класс модели, определив поля точно так же, как и в запросе материализованного представления. Класс модели должен иметь: * опцию managed, которую нужно установить в false в определении мета-класса для указания того, что схема базы данных не…
django.db.models import fields
from django.db.models.expressions import Combinable, ExpressionWrapper, F
class MaterializedViewField(fields.Field):
def __init__(self, child, source=None, **kwargs):
super().__init__(**kwargs)
self.child = child
if isinstance(source, Combinable) or source is None:
self.source = source
elif isinstance(source, str):
self.source = ExpressionWrapper(F(source), output_field=child)
else:
self.source = None
def deconstruct(self):
"""
Переопределение метода deconstruct для включения атрибутов пользовательских полей в файлы миграции
при выполнении команды `makemigrations` в отншении модели материализованного представления.
"""
name, path, args, keywords = super().deconstruct()
keywords.update(
source=self.source, child=self.child
)
return name, path, args, keywords
Шаг 3. Создание пользовательского движка базы данных для PostgreSQL
Следующий шаг — создание пользовательского движка базы данных с пользовательским классом редактора. Этот движок отвечает за реализацию необходимой настройки схемы.
Чтобы настроить редактор схем баз данных Django, нужно определить новый движок базы данных в проекте и сослаться на него в атрибуте
Обратите внимание: пользовательский движок базы данных нужно поместить в каталог с файлом
За дополнительной информацией обратитесь к документации Django.
Ниже приведен пример структуры папок, где движок базы данных помещен в приложение Django под названием core и в подпапку backends.
project_root/
...
django_project/
__init__.py
settings.py
core/
__init__.py
backends/
__init__.py
db/
__init__.py
base.py
Следующий код является примером пользовательского движка базы данных (он расположен в файле
from django.apps import apps
from django.db.backends.postgresql import base
from django.db.models import QuerySet, options, Model
from api.fields import MaterializedViewField
class DatabaseSchemaEditor(base.DatabaseSchemaEditor):
sql_create_materialized_view = "CREATE MATERIALIZED VIEW %(table)s AS %(definition)s"
sql_delete_materialized_view = "DROP MATERIALIZED VIEW %(table)s"
sql_refresh_materialized_View = "REFRESH MATERIALIZED VIEW %(concurrently)s %(view)s"
@staticmethod
def model_meta(model: type[Model]) -> options.Options:
return model._meta
def _get_parent_model(self, model: type[Model]):
"""
Возвращает базовую модель представления, которая будет использоваться для генерации SQL материализованного представления.
"""
parent_model = getattr(self.model_meta(model), 'view_parent_model', None)
if parent_model:
return apps.get_model(*parent_model.split('.'))
def model_is_materialized_view(self, model: type[Model]) -> bool:
"""Проверяет, является ли класс модели моделью материализованного представления или обычной моделью django."""
return getattr(self.model_meta(model), 'materialized_view', False)
def get_queryset(self, model: Model, extra_field=None):
"""Генерирует набор запросов из предоставленной родительской модели и предоставленных полей."""
def append_field(_model_field):
if _model_field.source is None:
concrete_fields.append(_model_field.name)
else:
annotation_fields.update({_model_field.attname: _model_field.source})
concrete_fields = []
annotation_fields = dict()
for field_name, field in model.__dict__.items():
if hasattr(field, 'field'):
model_field: MaterializedViewField = field.field
if isinstance(model_field, MaterializedViewField):
append_field(model_field)
if extra_field:
append_field(extra_field)
return QuerySet(
model=self._get_parent_model(model)
).only(*concrete_fields).annotate(**annotation_fields).query
def create_model(self, model, extra_field=None):
if self.model_is_materialized_view(model):
sql = self.sql[...]
from django.db.models.expressions import Combinable, ExpressionWrapper, F
class MaterializedViewField(fields.Field):
def __init__(self, child, source=None, **kwargs):
super().__init__(**kwargs)
self.child = child
if isinstance(source, Combinable) or source is None:
self.source = source
elif isinstance(source, str):
self.source = ExpressionWrapper(F(source), output_field=child)
else:
self.source = None
def deconstruct(self):
"""
Переопределение метода deconstruct для включения атрибутов пользовательских полей в файлы миграции
при выполнении команды `makemigrations` в отншении модели материализованного представления.
"""
name, path, args, keywords = super().deconstruct()
keywords.update(
source=self.source, child=self.child
)
return name, path, args, keywords
Шаг 3. Создание пользовательского движка базы данных для PostgreSQL
Следующий шаг — создание пользовательского движка базы данных с пользовательским классом редактора. Этот движок отвечает за реализацию необходимой настройки схемы.
Чтобы настроить редактор схем баз данных Django, нужно определить новый движок базы данных в проекте и сослаться на него в атрибуте
ENGINE
записи DATABASES
в файле настроек проекта.Обратите внимание: пользовательский движок базы данных нужно поместить в каталог с файлом
base.py
и классом DatabaseWrapper
.За дополнительной информацией обратитесь к документации Django.
Ниже приведен пример структуры папок, где движок базы данных помещен в приложение Django под названием core и в подпапку backends.
project_root/
...
django_project/
__init__.py
settings.py
core/
__init__.py
backends/
__init__.py
db/
__init__.py
base.py
Следующий код является примером пользовательского движка базы данных (он расположен в файле
base.py
).from django.apps import apps
from django.db.backends.postgresql import base
from django.db.models import QuerySet, options, Model
from api.fields import MaterializedViewField
class DatabaseSchemaEditor(base.DatabaseSchemaEditor):
sql_create_materialized_view = "CREATE MATERIALIZED VIEW %(table)s AS %(definition)s"
sql_delete_materialized_view = "DROP MATERIALIZED VIEW %(table)s"
sql_refresh_materialized_View = "REFRESH MATERIALIZED VIEW %(concurrently)s %(view)s"
@staticmethod
def model_meta(model: type[Model]) -> options.Options:
return model._meta
def _get_parent_model(self, model: type[Model]):
"""
Возвращает базовую модель представления, которая будет использоваться для генерации SQL материализованного представления.
"""
parent_model = getattr(self.model_meta(model), 'view_parent_model', None)
if parent_model:
return apps.get_model(*parent_model.split('.'))
def model_is_materialized_view(self, model: type[Model]) -> bool:
"""Проверяет, является ли класс модели моделью материализованного представления или обычной моделью django."""
return getattr(self.model_meta(model), 'materialized_view', False)
def get_queryset(self, model: Model, extra_field=None):
"""Генерирует набор запросов из предоставленной родительской модели и предоставленных полей."""
def append_field(_model_field):
if _model_field.source is None:
concrete_fields.append(_model_field.name)
else:
annotation_fields.update({_model_field.attname: _model_field.source})
concrete_fields = []
annotation_fields = dict()
for field_name, field in model.__dict__.items():
if hasattr(field, 'field'):
model_field: MaterializedViewField = field.field
if isinstance(model_field, MaterializedViewField):
append_field(model_field)
if extra_field:
append_field(extra_field)
return QuerySet(
model=self._get_parent_model(model)
).only(*concrete_fields).annotate(**annotation_fields).query
def create_model(self, model, extra_field=None):
if self.model_is_materialized_view(model):
sql = self.sql[...]
Django Unleashed Framework
django.db.models import fields from django.db.models.expressions import Combinable, ExpressionWrapper, F class MaterializedViewField(fields.Field): def __init__(self, child, source=None, **kwargs): super().__init__(**kwargs) self.child = child if isinstance(source…
_create_materialized_view % {
'table': self.quote_name(self.model_meta(model).db_table),
'definition': self.get_queryset(model, extra_field=extra_field)
}
self.execute(sql)
else:
super().create_model(model)
def add_field(self, model: Model, field):
if self.model_is_materialized_view(model):
setattr(model, field.attname, field)
self.delete_model(model)
self.create_model(model, extra_field=field)
else:
super().add_field(model, field)
def remove_field(self, model, field):
if self.model_is_materialized_view(model):
delattr(model, field.attname)
self.delete_model(model)
self.create_model(model)
else:
super().remove_field(model, field)
def alter_field(self, model, old_field, new_field, strict=False):
if self.model_is_materialized_view(model):
delattr(model, old_field.attname)
self.delete_model(model)
self.create_model(model, extra_field=new_field)
else:
super().alter_field(model, old_field, new_field, strict)
def delete_model(self, model):
if self.model_is_materialized_view(model):
self.execute(
self.sql_delete_materialized_view % {
"table": self.model_meta(model).db_table
}
)
else:
super().delete_model(model)
def refresh_materialized_view(self, model: type[Model], concurrent=False):
"""
Выполняет запрос на обновление материализованного представления,
если было желательно заполнять данные представления по требованию.
"""
self.execute(self.sql_refresh_materialized_View % {
'view': model._meta.db_table,
'concurrently': 'CONCURRENTLY' if concurrent else ''
})
class DatabaseWrapper(base.DatabaseWrapper):
SchemaEditorClass = DatabaseSchemaEditor
Приведенный выше код переопределяет встроенный в Django класс схемы базы данных postgres для поддержки выполнения запросов, необходимых для создания материализованных представлений после выполнения команды migrate.
Короче говоря, все методы работы с базой данных были модифицированы, чтобы проверить, является ли модель моделью материализованного представления или моделью обычного класса. Если это модель материализованного представления, будет вызван метод
Наконец, добавим пользовательский движок базы данных в настройки базы данных проекта следующим образом:
DATABASES = {
'default': {
'ENGINE': 'core.backends.db',
'HOST': '<db-host',
'NAME': '<db-name',
'USER': '<user',
'PASSWORD': '<passwrod',
'PORT': 5432,
'ATOMIC_REQUESTS': True,
}
}
Шаг 4. Собираем все вместе
Теперь продемонстрирую использование материализованного представления на нескольких примерах моделей. Определение модели в основном представляет собой простую модель Post с отношением “многие ко многим” с моделями Comment и Tag, как показано в примере ниже:
class Tag(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'Comment by {self.author.username} on {self.post.title}'
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
tags = models.ManyToManyField(Tag)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
Затем необходимо провести миграцию моделей, последовательно используя команды
$ python manage.py makemigraitons
$ python manage.py migrate
После того как все модели перенесены в базу данных, нужно создать определение модели материализованного представлен[...]
'table': self.quote_name(self.model_meta(model).db_table),
'definition': self.get_queryset(model, extra_field=extra_field)
}
self.execute(sql)
else:
super().create_model(model)
def add_field(self, model: Model, field):
if self.model_is_materialized_view(model):
setattr(model, field.attname, field)
self.delete_model(model)
self.create_model(model, extra_field=field)
else:
super().add_field(model, field)
def remove_field(self, model, field):
if self.model_is_materialized_view(model):
delattr(model, field.attname)
self.delete_model(model)
self.create_model(model)
else:
super().remove_field(model, field)
def alter_field(self, model, old_field, new_field, strict=False):
if self.model_is_materialized_view(model):
delattr(model, old_field.attname)
self.delete_model(model)
self.create_model(model, extra_field=new_field)
else:
super().alter_field(model, old_field, new_field, strict)
def delete_model(self, model):
if self.model_is_materialized_view(model):
self.execute(
self.sql_delete_materialized_view % {
"table": self.model_meta(model).db_table
}
)
else:
super().delete_model(model)
def refresh_materialized_view(self, model: type[Model], concurrent=False):
"""
Выполняет запрос на обновление материализованного представления,
если было желательно заполнять данные представления по требованию.
"""
self.execute(self.sql_refresh_materialized_View % {
'view': model._meta.db_table,
'concurrently': 'CONCURRENTLY' if concurrent else ''
})
class DatabaseWrapper(base.DatabaseWrapper):
SchemaEditorClass = DatabaseSchemaEditor
Приведенный выше код переопределяет встроенный в Django класс схемы базы данных postgres для поддержки выполнения запросов, необходимых для создания материализованных представлений после выполнения команды migrate.
Короче говоря, все методы работы с базой данных были модифицированы, чтобы проверить, является ли модель моделью материализованного представления или моделью обычного класса. Если это модель материализованного представления, будет вызван метод
get_queryset
, чтобы сгенерировать необработанный SQL-запрос из родительской модели для создания или обновления материализованного представления. В противном случае родительский метод будет вызван как обычно.Наконец, добавим пользовательский движок базы данных в настройки базы данных проекта следующим образом:
DATABASES = {
'default': {
'ENGINE': 'core.backends.db',
'HOST': '<db-host',
'NAME': '<db-name',
'USER': '<user',
'PASSWORD': '<passwrod',
'PORT': 5432,
'ATOMIC_REQUESTS': True,
}
}
Шаг 4. Собираем все вместе
Теперь продемонстрирую использование материализованного представления на нескольких примерах моделей. Определение модели в основном представляет собой простую модель Post с отношением “многие ко многим” с моделями Comment и Tag, как показано в примере ниже:
class Tag(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'Comment by {self.author.username} on {self.post.title}'
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
tags = models.ManyToManyField(Tag)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
Затем необходимо провести миграцию моделей, последовательно используя команды
makemigrations
и migrate
.$ python manage.py makemigraitons
$ python manage.py migrate
После того как все модели перенесены в базу данных, нужно создать определение модели материализованного представлен[...]
Django Unleashed Framework
_create_materialized_view % { 'table': self.quote_name(self.model_meta(model).db_table), 'definition': self.get_queryset(model, extra_field=extra_field) } self.execute(sql) else: super().create_model(model) def add_field(self, model: Model, field): if s…
ия для модели Post.
class MaterializedViewBaseModel(models.Model):
class Meta:
abstract = True
@classmethod
def check(cls, **kwargs):
errors = super().check(**kwargs)
if not hasattr(cls._meta, 'materialized_view'):
errors.append(
checks.Error(
'The `view` attribute is required in materialized view meta class.',
obj=cls,
id='models.E100',
)
)
view_parent_model = getattr(cls._meta, 'view_parent_model', None)
if view_parent_model:
try:
apps.get_model(*getattr(cls._meta, 'view_parent_model').split('.'))
except (LookupError, ValueError) as e:
errors.append(
checks.Error(
f"Invalid `view_parent_model` format, {e}", obj=cls, id='models.E101'
)
)
else:
errors.append(
checks.Error(
'The `view_parent_model` attribute is required in materialized view meta class.',
obj=cls,
id='models.E101'
)
)
return errors
@classmethod
def refresh(cls, concurrent=False):
with connection.cursor() as cursor:
editor = cursor.db.schema_editor()
editor.refresh_materialized_view(cls, concurrent=concurrent)
class PostMaterializedView(MaterializedViewBaseModel):
post_id = MaterializedViewField(source='pk', child=models.IntegerField())
title = MaterializedViewField(child=models.CharField())
content = MaterializedViewField(child=models.CharField())
tag_names = MaterializedViewField(
source=aggregates.StringAgg('tags__name', delimiter="'; '", distinct=True),
child=models.CharField()
)
comments_count = MaterializedViewField(
source=functions.Coalesce(models.Count('comments', distinct=True), 0),
child=models.IntegerField()
)
comment_authors = MaterializedViewField(
source=aggregates.StringAgg(
'comments__author__first_name', delimiter="', '", distinct=True
),
child=models.CharField()
)
class Meta:
view_parent_model = 'api.Post'
materialized_view = True
constraints = [
models.UniqueConstraint(
models.F('post_id'), name='unique_post_id',
)
]
В приведенном выше примере пользовательские
Поле модели
Материализованный абстрактный класс в основном выполняет проверки пользовательских атрибутов класса
Наконец, последовательное выполнение команд
# Сгенерировано Django 4.2.1 2023.05.22 в 22:10
import api.fields
import django.contrib.postgres.aggregates.general
from django.db import migrations, models
import django.db.models.aggregates
import django.db.models.functions.comparison
class Migration(migrations.Migration):
dependencies = [
("api", "0001_initial"),
]
operations = [
migrations.CreateModel(
name="PostMaterializedView",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"post_id",
api.fields.MaterializedViewField(
child=models.IntegerField(),
source=models.ExpressionWrapper(
models.F("pk"), output_field=models.IntegerField()
),
),
),
(
"title",
api.fields.MaterializedViewField(
child=models.CharField(), source=None
),
),
(
"content",
api.fields.MaterializedViewField(
child=models.CharField(), source=Non[...]
class MaterializedViewBaseModel(models.Model):
class Meta:
abstract = True
@classmethod
def check(cls, **kwargs):
errors = super().check(**kwargs)
if not hasattr(cls._meta, 'materialized_view'):
errors.append(
checks.Error(
'The `view` attribute is required in materialized view meta class.',
obj=cls,
id='models.E100',
)
)
view_parent_model = getattr(cls._meta, 'view_parent_model', None)
if view_parent_model:
try:
apps.get_model(*getattr(cls._meta, 'view_parent_model').split('.'))
except (LookupError, ValueError) as e:
errors.append(
checks.Error(
f"Invalid `view_parent_model` format, {e}", obj=cls, id='models.E101'
)
)
else:
errors.append(
checks.Error(
'The `view_parent_model` attribute is required in materialized view meta class.',
obj=cls,
id='models.E101'
)
)
return errors
@classmethod
def refresh(cls, concurrent=False):
with connection.cursor() as cursor:
editor = cursor.db.schema_editor()
editor.refresh_materialized_view(cls, concurrent=concurrent)
class PostMaterializedView(MaterializedViewBaseModel):
post_id = MaterializedViewField(source='pk', child=models.IntegerField())
title = MaterializedViewField(child=models.CharField())
content = MaterializedViewField(child=models.CharField())
tag_names = MaterializedViewField(
source=aggregates.StringAgg('tags__name', delimiter="'; '", distinct=True),
child=models.CharField()
)
comments_count = MaterializedViewField(
source=functions.Coalesce(models.Count('comments', distinct=True), 0),
child=models.IntegerField()
)
comment_authors = MaterializedViewField(
source=aggregates.StringAgg(
'comments__author__first_name', delimiter="', '", distinct=True
),
child=models.CharField()
)
class Meta:
view_parent_model = 'api.Post'
materialized_view = True
constraints = [
models.UniqueConstraint(
models.F('post_id'), name='unique_post_id',
)
]
В приведенном выше примере пользовательские
Options
класса Meta
были определены для информирования редактора схемы базы данных о том, что модель является материализованным представлением, и генерации SQL-запроса из модели Post
.Поле модели
MaterializedViewField
было использовано для определения полей модели, предоставляющих поле дочерней модели и атрибут источника. Важно отметить, что поле модели было специально разработано для поддержки различных выражений запросов базы данных, упомянутых в документации Django, включая F
, StringAggr
, Count
, Avg
, Sum
, Case
и так далее.Материализованный абстрактный класс в основном выполняет проверки пользовательских атрибутов класса
Meta
. Например, проверяет существование атрибутов materialized_view
и view_parent_model
и уточняет был ли view_parent_model
определен в правильном формате.Наконец, последовательное выполнение команд
makemigrations
и migrate
должно создать новое материализованное представление, легко используемое в Django для выполнения запросов и операций фильтрации.# Сгенерировано Django 4.2.1 2023.05.22 в 22:10
import api.fields
import django.contrib.postgres.aggregates.general
from django.db import migrations, models
import django.db.models.aggregates
import django.db.models.functions.comparison
class Migration(migrations.Migration):
dependencies = [
("api", "0001_initial"),
]
operations = [
migrations.CreateModel(
name="PostMaterializedView",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"post_id",
api.fields.MaterializedViewField(
child=models.IntegerField(),
source=models.ExpressionWrapper(
models.F("pk"), output_field=models.IntegerField()
),
),
),
(
"title",
api.fields.MaterializedViewField(
child=models.CharField(), source=None
),
),
(
"content",
api.fields.MaterializedViewField(
child=models.CharField(), source=Non[...]
Django Unleashed Framework
ия для модели Post. class MaterializedViewBaseModel(models.Model): class Meta: abstract = True @classmethod def check(cls, **kwargs): errors = super().check(**kwargs) if not hasattr(cls._meta, 'materialized_view'): errors.append( checks.Error( 'The `view`…
e
),
),
(
"tag_names",
api.fields.MaterializedViewField(
child=models.CharField(),
source=django.contrib.postgres.aggregates.general.StringAgg(
"tags__name", delimiter="'; '", distinct=True
),
),
),
(
"comments_count",
api.fields.MaterializedViewField(
child=models.IntegerField(),
source=django.db.models.functions.comparison.Coalesce(
django.db.models.aggregates.Count(
"comments", distinct=True
),
0,
),
),
),
(
"comment_authors",
api.fields.MaterializedViewField(
child=models.CharField(),
source=django.contrib.postgres.aggregates.general.StringAgg(
"comments__author__first_name",
delimiter="', '",
distinct=True,
),
),
),
],
options={
"materialized_view": True,
"view_parent_model": "api.Post",
},
),
migrations.AddConstraint(
model_name="postmaterializedview",
constraint=models.UniqueConstraint(
models.F("post_id"), name="unique_post_id"
),
),
]
Обратите внимание: атрибуты
Теперь Django успешно интегрирован с материализованными представлениями PostgreSQL.
Следующие шаги
Хотя нам удалось внедрить в Django новую функцию для использования материализованных представлений PostgreSQL, есть несколько улучшений, достойных обсуждения.
Поскольку теперь ясно, что материализованные представления нуждаются в регулярных обновлениях в случае, если базовая таблица представления была обновлена, необходимо разработать механизм для поддержания данных материализованного представления в актуальном состоянии.
На предложенном решении можно протестировать более сложные примеры, чтобы проверить его динамичность для различных типов запросов и случаев использования.
Заключение
Надеюсь, это руководство позволит вам легко интегрировать материализованные представления в приложения Django. Для этого потребуется запустить такие механизмы, как переопределение класса схемы базы данных, разработка пользовательских классов модели и разработка пользовательских полей модели.
Благодаря возможности создавать и обновлять материализованные представления с помощью системы миграции Django, вы сможете поддерживать синхронизацию между схемой базы данных и определениями моделей. Разделение обычных моделей и моделей материализованных представлений улучшает организацию и удобство сопровождения кода.
Читайте также:
* Как загружать файлы и изображения в приложении Django
* Как заказывали: админ-панель от Django Jet
* Простой прием для молниеносных запросов LIKE и ILIKE
Читайте нас в Telegram, VK и Дзен
Перевод статьи Abdulla Hashim: Integrating Django with PostgreSQL Materialized Views
Читать: Интеграция Django с материализованными представлениями PostgreSQL .
),
),
(
"tag_names",
api.fields.MaterializedViewField(
child=models.CharField(),
source=django.contrib.postgres.aggregates.general.StringAgg(
"tags__name", delimiter="'; '", distinct=True
),
),
),
(
"comments_count",
api.fields.MaterializedViewField(
child=models.IntegerField(),
source=django.db.models.functions.comparison.Coalesce(
django.db.models.aggregates.Count(
"comments", distinct=True
),
0,
),
),
),
(
"comment_authors",
api.fields.MaterializedViewField(
child=models.CharField(),
source=django.contrib.postgres.aggregates.general.StringAgg(
"comments__author__first_name",
delimiter="', '",
distinct=True,
),
),
),
],
options={
"materialized_view": True,
"view_parent_model": "api.Post",
},
),
migrations.AddConstraint(
model_name="postmaterializedview",
constraint=models.UniqueConstraint(
models.F("post_id"), name="unique_post_id"
),
),
]
Обратите внимание: атрибуты
source
и child
поля MaterializedViewField
были включены в файл миграции, так как мы определили их в методе deconstruct
поля.Теперь Django успешно интегрирован с материализованными представлениями PostgreSQL.
Следующие шаги
Хотя нам удалось внедрить в Django новую функцию для использования материализованных представлений PostgreSQL, есть несколько улучшений, достойных обсуждения.
Поскольку теперь ясно, что материализованные представления нуждаются в регулярных обновлениях в случае, если базовая таблица представления была обновлена, необходимо разработать механизм для поддержания данных материализованного представления в актуальном состоянии.
На предложенном решении можно протестировать более сложные примеры, чтобы проверить его динамичность для различных типов запросов и случаев использования.
Заключение
Надеюсь, это руководство позволит вам легко интегрировать материализованные представления в приложения Django. Для этого потребуется запустить такие механизмы, как переопределение класса схемы базы данных, разработка пользовательских классов модели и разработка пользовательских полей модели.
Благодаря возможности создавать и обновлять материализованные представления с помощью системы миграции Django, вы сможете поддерживать синхронизацию между схемой базы данных и определениями моделей. Разделение обычных моделей и моделей материализованных представлений улучшает организацию и удобство сопровождения кода.
Читайте также:
* Как загружать файлы и изображения в приложении Django
* Как заказывали: админ-панель от Django Jet
* Простой прием для молниеносных запросов LIKE и ILIKE
Читайте нас в Telegram, VK и Дзен
Перевод статьи Abdulla Hashim: Integrating Django with PostgreSQL Materialized Views
Читать: Интеграция Django с материализованными представлениями PostgreSQL .
😱3🤔1
5 Django Commands Every Developer Should Know
django-admin startproject
This command is used to create a new Django project. It sets up the basic directory structure and configuration files for a Django project. For example, running django-admin startproject mylibrary will create a new project ...
Read: https://codepriest.hashnode.dev/5-django-commands-every-developer-should-know
django-admin startproject
This command is used to create a new Django project. It sets up the basic directory structure and configuration files for a Django project. For example, running django-admin startproject mylibrary will create a new project ...
Read: https://codepriest.hashnode.dev/5-django-commands-every-developer-should-know
Free Services to Support Development of a Django App I
Introduction
When we are hosting a website using cloud services, we know that the process can be quite expensive. So it makes sense for us to stick to as many free services as we can during the development phase.
Here are 5 different services that we...
Read: https://diptonil.hashnode.dev/free-services-to-support-development-of-a-django-app-i
Introduction
When we are hosting a website using cloud services, we know that the process can be quite expensive. So it makes sense for us to stick to as many free services as we can during the development phase.
Here are 5 different services that we...
Read: https://diptonil.hashnode.dev/free-services-to-support-development-of-a-django-app-i
Structuring Your Django Template The Right Way
Introduction
Templates play a vital role in Django's MVT (Model-View-Template) structure. In simple terms, a Django template is like a particular HTML file written in languages like HTML, CSS, and Javascript. These templates create the visual appeara...
Read: https://faithbolanle.hashnode.dev/structuring-your-django-template-the-right-way
Introduction
Templates play a vital role in Django's MVT (Model-View-Template) structure. In simple terms, a Django template is like a particular HTML file written in languages like HTML, CSS, and Javascript. These templates create the visual appeara...
Read: https://faithbolanle.hashnode.dev/structuring-your-django-template-the-right-way
Choosing the Right Framework: Laravel, Django, or React?
In the world of web development, selecting the right framework is crucial to ensure efficient and successful project outcomes. Laravel, Django, and React are three popular choices that developers often consider.
Before hardcore developer comes at me...
Read: https://scofield.hashnode.dev/choosing-the-right-framework-laravel-django-or-react
In the world of web development, selecting the right framework is crucial to ensure efficient and successful project outcomes. Laravel, Django, and React are three popular choices that developers often consider.
Before hardcore developer comes at me...
Read: https://scofield.hashnode.dev/choosing-the-right-framework-laravel-django-or-react
👍1