Share This
Связаться со мной
Крути в низ
Categories
//Django. Часть 2: ORM и основы работы с базами данных

Django. Часть 2: ORM и основы работы с базами данных

Создаем базу данных на основе моделей, рассматриваем способы наполнения БД с использованием loaddata и скриптов. Передаем данные на фронтенд с помощью функциональных представлений и шаблонов.

django chast 2 orm i osnovy raboty s bazami dannyh 97de451 - Django. Часть 2: ORM и основы работы с базами данных

← Проект 1 Веб-приложение на основе XLSX вместо базы данных ← Часть 1 Django — что это? Обзор и установка фреймворка, структура проекта

Для создания базы данных (и всех взаимодействий с ней) Django использует ORM (объектно-реляционное представление). ORM – это своеобразная прослойка, которая позволяет работать с базой данных, используя классы и методы вместо написания сложных SQL-запросов.

Вот основные возможности и преимущества использования ORM в Django:

  • Моделирование базы данных. Разработчик определяет структуру таблиц, их поля и взаимосвязи между ними с помощью специальных классов – моделей.
  • Отношения и связи. Связывание моделей различными типами отношений (один-к-одному, один-ко-многим и многие-ко-многим) в ORM выполняется очень просто.
  • Простой доступ к данным. Запросы к базе данных выполняются с помощью простого и понятного синтаксиса вместо языка SQL.
  • Гибкое обновление структуры базы данных. С помощью миграций ORM мгновенно изменяет структуру базы данных в соответствии с изменениями в моделях.
  • Автоматическая валидация данных. ORM предусматривает несколько способов автоматической валидации данных в соответствии с определенными правилами и ограничениями.
  • Защита от SQL-инъекций. Код SQL запроса определяется отдельно от параметров запроса.
  • Переносимость – можно легко переключаться между разными базами данных, не меняя код приложения.
  • Кеширование запросов для повышения производительности.
  • Разнообразная дополнительная функциональность – ORM предоставляет готовые решения для работы с данными: создание и изменение объектов, выборки, агрегации, пагинация и т.д. Не нужно все это программировать вручную.

Недостатки у ORM тоже есть, но их гораздо меньше, чем преимуществ:

  • Снижение производительности. ORM добавляет накладные расходы, так как создает дополнительный слой абстракции над базой данных. В некоторых случаях использование ORM может привести к уменьшению производительности из-за неоптимальных запросов.
  • Для написания сложных запросов (и для оптимизации часто повторяющихся, ресурсоемких операций) могут потребоваться Q и F-объекты.
  • В некоторых случаях сложные запросы нужно писать вручную на SQL.

? Библиотека питониста Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека питониста» ?? Библиотека собеса по Python Подтянуть свои знания по Python вы можете на нашем телеграм-канале «Библиотека собеса по Python» ?? Библиотека задач по Python» Интересные задачи по Python для практики можно найти на нашем телеграм-канале «Библиотека задач по Python»

Модели в Django

Модели в Django представляют собой классы Python, которые описывают структуру, свойства и взаимосвязи таблиц в базе данных. Модели не только играют ключевую роль в создании и управлении схемой базы данных, но также обеспечивают удобный интерфейс для работы с данными.

Модели содержат поля, которые представляют столбцы в таблице БД. Эти поля определяют тип данных, валидацию и другие свойства для хранения, извлечения и обновления данных. Например, поле типа CharField может описывать строковое значение, поле типа DateField – дату, а поле типа ForeignKey – отношение типа один-ко-многим между таблицами. Кроме полей, для модели можно определять метаданные, методы, менеджеры для выборки и фильтрации данных.

Связи между моделями

Основные типы связей между моделями – один-к-одному, один-ко-многим, многие-ко-многим. Рассмотрим на примерах.

Один-к-одному (OneToOne) – это связь одной записи в одной таблице с одной записью в другой таблице. Например, один пользователь может иметь только один профиль:

         class User(models.Model):     name = models.CharField(max_length=50)  class Profile(models.Model):     user = models.OneToOneField(User, on_delete=models.CASCADE)     bio = models.TextField(blank=True)     avatar = models.ImageField(upload_to='avatars/', blank=True)     

Один-ко-многим (ForeignKey) – это связь одной записи в одной таблице со многими записями в другой. Например, один автор может написать несколько книг:

         class Author(models.Model):    name = models.CharField(max_length=50)  class Book(models.Model):    author = models.ForeignKey(Author, on_delete=models.CASCADE)    title = models.CharField(max_length=50)     

Многие-ко-многим (ManyToMany) – это связь между произвольным количеством записей в двух таблицах. Например, одна книга может принадлежать к нескольким жанрам сразу, а к одному жанру относится множество книг:

         class Genre(models.Model):     name = models.CharField(max_length=50)  class Book(models.Model):     title = models.CharField(max_length=50)     genres = models.ManyToManyField(Genre)     

Статья по теме ? Самоучитель по Python для начинающих. Часть 22: Основы работы с SQLite

Создание базы данных в Django

Для создания базы данных в Django нужно:

  • Создать первичную базу с помощью команды migrate.
  • Создать аккаунт суперпользователя (админа) командой createsuperuser.
  • Написать модели, определяющие нужную структуру БД.
  • Подготовить и выполнить миграции – makemigrations и migrate.

Выполним все эти действия шаг за шагом.

Инициализация базы данных

Django по умолчанию использует SQLite, и для подключения этой базы к приложению (в отличие от других баз типа MySQL и PostgreSQL) не нужно делать никаких специальных настроек. Как только вы создали проект и приложение в нем, можно выполнить команду migrate, что приведет к появлению базы данных db.sqlite3 на одном уровне с директорией приложения и файлом manage.py:

         python -m venv myprojectvenv cd myproject venvscriptsactivate pip install django django-admin startproject config . python manage.py startapp myapp python manage.py migrate python manage.py createsuperuser      

Структура проекта теперь выглядит так:

         myproject |-- config |   |-- __init__.py |   |-- settings.py |   |-- urls.py |   `-- wsgi.py |-- myapp |   |-- __init__.py |   |-- admin.py |   |-- apps.py |   |-- models.py   |   |-- tests.py |   |-- views.py |   `-- migrations |-- venv |-- db.sqlite3   `-- manage.py     

Добавьте приложение myapp в config/settings.py:

         INSTALLED_APPS = [     'myapp.apps.MyappConfig',     'django.contrib.admin',     'django.contrib.auth',     'django.contrib.contenttypes',     'django.contrib.sessions',     'django.contrib.messages',     'django.contrib.staticfiles', ]     

Создание структуры базы данных

Сохраните в файле myapp/models.py модели Author, Genre и Book:

         from django.db import models  class Author(models.Model):     first_name = models.CharField(max_length=50)     last_name = models.CharField(max_length=50)     biography = models.TextField(blank=True)      class Genre(models.Model):     name = models.CharField(max_length=50)     description = models.TextField(blank=True)  class Book(models.Model):     title = models.CharField(max_length=100)         description = models.TextField()        publication_date = models.DateField()        num_pages = models.IntegerField()        price = models.DecimalField(max_digits=6, decimal_places=2)        genres = models.ManyToManyField(Genre)      author = models.ForeignKey(Author, on_delete=models.CASCADE)     is_bestseller = models.BooleanField(default=False)      

Теперь можно подготовить миграции (изменения в структуре) БД:

         python manage.py migrate     

И применить миграции к структуре БД:

         python manage.py migrate     

В базе данных появились соответствующие таблицы Author, Genre и Book. Вот какие значения там можно сохранять:

  • CharField – строка ограниченной длины, для небольших текстовых значений вроде имен и названий.
  • TextField – неограниченный текст, для мультистрочных текстов вроде подробных описаний.
  • DateField – дата, хранится в формате ГГГГ-ММ-ДД.
  • IntegerField – целочисленное значение.
  • DecimalField – число с плавающей точкой, для денежных значений. Это более точный формат, чем FloatField.
  • ForeignKey – ссылка на другую модель, связь один-ко-многим.
  • ManyToManyField – связь многие-ко-многим.
  • BooleanField – логическое значение True или False.

У моделей могут быть и другие поля – например, FileField для хранения ссылки на текстовый или аудиофайл книги, ImageField для ссылки на изображение обложки. Надо заметить, что файлы в базе данных обычно не хранят (хотя это возможно) – в соответствующих файлам полях сохраняются только ссылки на файлы, которые, в свою очередь, физически находятся в директории media и других служебных папках.

Статья по теме ?? Python + MySQL: как подключиться к СУБД MySQL и работать с ней с помощью Python

Регистрация моделей в панели управления Django

Чтобы с моделями можно было работать в админке Django, нужно их зарегистрировать в файле myapp/admin.py:

         from django.contrib import admin from .models import Author, Genre, Book  admin.site.register(Author) admin.site.register(Genre) admin.site.register(Book)      

Это самый простой способ представления моделей в админке, есть и более удобные. Например, так можно обеспечить вывод полей Book прямо на странице Author:

         from django.contrib import admin from .models import Author, Genre, Book  class BookInline(admin.TabularInline):     model = Book  class AuthorAdmin(admin.ModelAdmin):     inlines = [BookInline]  admin.site.register(Author, AuthorAdmin) admin.site.register(Genre) admin.site.register(Book)     

Теперь можно запустить сервер, зайти в админку и посмотреть на визуальное представление базы данных:

         python manage.py runserver     

Панель управления Django доступна по адресу http://127.0.0.1:8000/admin:

django chast 2 orm i osnovy raboty s bazami dannyh a9dc8f9 - Django. Часть 2: ORM и основы работы с базами данных

Панель управления Django доступна по адресу http://127.0.0.1:8000/admin

Класс Meta

Русскоязычные названия для моделей, порядок вывода записей, ограничения по уникальности и многое другое можно определить с помощью класса Meta:

         class Author(models.Model):     first_name = models.CharField(max_length=50)     last_name = models.CharField(max_length=50)     biography = models.TextField(blank=True)     class Meta:         ordering = ['-id']         verbose_name = 'Автор'         verbose_name_plural = 'Авторы'      def __str__(self):         return f'{self.first_name} {self.last_name}'      class Genre(models.Model):     name = models.CharField(max_length=50)     description = models.TextField(blank=True)     class Meta:         verbose_name = 'Жанр'         verbose_name_plural = 'Жанры'      def __str__(self):         return self.name  class Book(models.Model):     title = models.CharField(max_length=100)         description = models.TextField()        publication_date = models.DateField()        num_pages = models.IntegerField()        price = models.DecimalField(max_digits=6, decimal_places=2)        genres = models.ManyToManyField(Genre)      author = models.ForeignKey(Author, on_delete=models.CASCADE)     is_bestseller = models.BooleanField(default=False)     class Meta:     	ordering = ['-id']         verbose_name = 'Книга'         verbose_name_plural = 'Книги'      def __str__(self):         return self.title      

Статья по теме ?? Python и MySQL: практическое введение

Заполнение базы

Наполнить БД информацией можно несколькими способами:

  • Вручную в админке. Панель управления Django является, по сути, удобным визуальным GUI для CRUD-операций. Но записи придется вводить по одной.
  • В интерактивной оболочке (shell) Django. Так можно ввести сколько угодно записей за раз, однако набирать их придется вручную, а после каждого неверного отступа процесс нужно будет начинать сначала. В shell также можно загрузить данные из файла, ниже мы рассмотрим этот способ.
  • С помощью команды loaddata и данных из заранее подготовленного json-файла, структура которого соответствует схеме БД.
  • С помощью Python-скрипта, который может загрузить данные из любого файла (json, csv, xlsx), придать им нужную структуру и сохранить в базе. Такие скрипты можно выполнять в shell и в cmd.

Самый удобный из этих способов – загрузка с loaddata:

  • Сначала нужно создать директорию fixtures в папке приложения, то есть myapp/fixtures.
  • В директорию fixtures нужно поместить готовый json-файл с данными.
  • После чего надо выполнить команду python manage.py loaddata data.json.
         python manage.py loaddata data.json Installed 9 object(s) from 1 fixture(s)     

Запустите сервер, зайдите в админку – теперь там есть 3 жанра, 3 книги и 3 писателя:

django chast 2 orm i osnovy raboty s bazami dannyh df74f6f - Django. Часть 2: ORM и основы работы с базами данных

В админке появились 3 жанра, 3 книги и 3 писателя

А так можно добавлять записи в БД в интерактивной оболочке Django:

         python manage.py shell >>> from myapp.models import Author, Genre, Book >>> new_author = Author.objects.create(first_name='Дэн', last_name='Симмонс', biography='Современный американский писатель-фантаст') >>> print(Author.objects.all()) <QuerySet [<Author: Дэн Симмонс>, <Author: Джоан Роулинг>, <Author: Федор Достоевский>, <Author: Лев Толстой>]> >>> new_genre = Genre.objects.create(name='Триллер', description='В литературных произведениях этого жанра есть загадка и ощущение тревоги или страха.') >>> print(Genre.objects.all()) <QuerySet [<Genre: Роман>, <Genre: Повесть>, <Genre: Фантастика>, <Genre: Триллер>]> >>> new_book = Book.objects.create(title='Террор', description='Фантастическая версия трагической гибели арктической экспедиции Джона Франклина.', publication_date='2007-01-09', num_pages=1002, price=970.00, author=new_author, is_bestseller=True) >>> new_book.genres.add(new_genre)     

Результат – в базу добавлены записи о писателе Дэне Симмонсе, его книге «Террор», и одном из жанров, к которым относится эта книга – триллер:

django chast 2 orm i osnovy raboty s bazami dannyh ce4603c - Django. Часть 2: ORM и основы работы с базами данных

В базу добавлены записи о писателе Дэне Симмонсе, его книге «Террор»

Еще один способ – загрузка данных из скрипта, выполненного в shell:

  • Сохраните скрипт add_data.py на одном уровне с manage.py.
  • Запустите оболочку командой python manage.py shell.
  • Выполните команду exec(open("add_data.py", encoding="utf-8").read()).

Готово – в базе данных появились записи о двух новых авторах, книгах и жанрах:

django chast 2 orm i osnovy raboty s bazami dannyh 64672d3 - Django. Часть 2: ORM и основы работы с базами данных

В базе данных появились записи о двух новых авторах, книгах и жанрах Статья по теме ?? Пишем гибридное приложение для хранения заметок на Django, Django Ninja REST Framework и Alpine.js

Получение данных из БД

Все основные манипуляции с данными в Django происходят в представлениях, которые находятся в файле views.py. Представления делятся на функциональные и классовые. Представления на основе классов имеют несколько весомых преимуществ по сравнению с функциональными, и в дальнейшем мы подробно их рассмотрим.

Сохраните эти функциональные представления в myapp/views.py:

         from django.shortcuts import render from .models import Author, Book, Genre  def authors(request):     authors = Author.objects.all()     context = {         'authors': authors     }     return render(request, 'authors.html', context)  def books(request):     books = Book.objects.all()     context = {         'books': books     }     return render(request, 'books.html', context)  def genres(request):     genres = Genre.objects.all()     context = {         'genres': genres     }     return render(request, 'genres.html', context)     

Представления передают в шаблоны все записи об авторах, книгах и жанрах. В действие эти представления приводят маршруты. Сохраните эти маршруты в файле myapp/urls.py:

         from django.urls import path from .views import authors, books, genres  urlpatterns = [     path('authors/', authors, name='authors'),     path('books/', books, name='books'),     path('genres/', genres, name='genres') ]     

И добавьте маршруты myapp в config/urls.py:

         from django.contrib import admin from django.urls import path, include  urlpatterns = [     path('admin/', admin.site.urls),     path('', include('myapp.urls')),  ]      

Теперь нужно создать директорию templates внутри myapp и сохранить в ней эти шаблоны:

  • base.html
  • authors.html
  • books.html
  • genres.html

Все готово – запускайте сервер, переходите по ссылкам-маршрутам:

  • http://127.0.0.1:8000/authors/
  • http://127.0.0.1:8000/books/
  • http://127.0.0.1:8000/genres/

django chast 2 orm i osnovy raboty s bazami dannyh d9ccf1f - Django. Часть 2: ORM и основы работы с базами данных

http://127.0.0.1:8000/authors/

django chast 2 orm i osnovy raboty s bazami dannyh 4569f46 - Django. Часть 2: ORM и основы работы с базами данных

http://127.0.0.1:8000/books/

django chast 2 orm i osnovy raboty s bazami dannyh edf908d - Django. Часть 2: ORM и основы работы с базами данных

http://127.0.0.1:8000/genres/

Подведем итоги

Мы рассмотрели:

  • Принцип создания базы данных с помощью моделей ORM.
  • Способы заполнения БД с использованием loaddata, команды create() и скрипта, запускаемого в интерактивной оболочке shell.
  • Простейшие представления на основе функций.
  • Механизм передачи данных из БД на фронтенд.

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

Весь код и база данных, использованные в этой статье, находятся здесь.

***

Содержание курса

  • Часть 1: Django — что это? Обзор и установка фреймворка, структура проекта
  • Проект 1: Веб-приложение на основе XLSX вместо базы данных
  • Часть 2: ORM и основы работы с базами данных

  • 0 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Связаться со мной
Close