Перейдите к следующему слайду, нажав кнопку Вправо
Часто используемые команды при работе с Django ORM
Подготовлено онлайн-курсом
$ sudo apt-get update && sudo apt-get install -y python3 python3-pip
$ sudo pip3 install virtualenv
$ sudo virtualenv --python=$(which python3) env
$ . env/bin/activate
(env) $
Установка питона и виртуального окружения
(env) $ pip3 install django==2.2.6
(env) $ django-admin startproject mysite
(env) $ cd mysite
(env) $ python manage.py runserver 0.0.0.0:8000
Установка джанго и запуск проекта
Запуск shell
(env) $ python manage.py shell
Python 3.6.8 (default, Aug 20 2019, 17:12:48)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from your_app_name.models import Modelname
(env) $ python manage.py startapp app
Создание приложения
from django.contrib import admin
from .models import Author, Genre, Book, BookInstance
admin.site.register(Book)
admin.site.register(Author)
admin.site.register(Genre)
admin.site.register(BookInstance)
Регистрация моделей
Создание суперпользователя
python3 manage.py createsuperuser
Вход в админку по ссылке http://127.0.0.1:8000/admin/
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField()
published_date = models.DateTimeField()
Модель Post
>>> posts = Post.objects.all()
>>> print(posts)
>>> <QuerySet [<Post: Post object>, <Post: Post object>, <Post: Post object>]>
Как достать все данные о постах
Данные о постах в БД выглядят примерно так:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField()
published_date = models.DateTimeField()
>>> some_post = posts[0]
>>> print(some_post.title)
>>> Испытания дрейфующего стратостата. Запуск Рогозина и LoRa в стратосферу
Модель Post
Как достать данные из объекта
Выводим заголовок одного поста
Выводим заголовок всех постов
>>> for post in posts:
print(post.title)
>>> Испытания дрейфующего стратостата. Запуск Рогозина и LoRa в стратосферу
Telegram. Безлимитный сетевой диск. Бесплатный
13 самых заминусованных статей минувшего года
Почему ['1', '7', '11'].map(parseInt) возвращает [1, NaN, 3] в Javascript?
...
Данные о постах в БД выглядят примерно так:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
text = models.TextField()
is_deleted = models.BooleanField()
is_published = models.BooleanField()
Модель Post
published_posts = Post.objects.filter(is_published=True)
deleted_posts = Post.objects.filter(is_deleted=True)
non_published_posts = Post.objects.filter(is_published=False)
non_deleted_posts = Post.objects.filter(is_deleted=False)
Фильтрация по одному полю
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
text = models.TextField()
is_deleted = models.BooleanField()
is_published = models.BooleanField()
Модель Post
Фильтрация по нескольким полям
posts_to_show = Post.objects.filter(is_published=True, is_deleted=False)
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
text = models.TextField()
is_deleted = models.BooleanField()
is_published = models.BooleanField()
Модель Post
Операции сравнения
searched_posts = Post.objects.filter(title__contains="питон")
Заголовок содержит строку "питон":
`__gt` — (greater then, в переводе, "больше чем") проверяет, что поле больше, чем то, что передадут справа.
Пример: `filter(likes__gt=10)` — фильтруем посты, у которых больше 10 лайков.
`__lt` — (less then, "меньше чем) аналогично, проверяет, что поле меньше.
Чтобы проверить условие "больше или равно", есть операция сравнения `__gte`,
а "меньше ли равно" — `__lte`.
from django.db import models
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.SET_NULL)
...
Модель Post
from django.db import models
class User(models.Model):
login = models.CharField(max_length=200)
email = models.EmailField()
birthday = models.DateField()
avatar = models.ImageField()
...
Модель User
ForeignKey — это особый вид поля. Он говорит о том, что здесь мы храним ссылку на другую таблицу. Теперь можно быстро добраться до автора поста, который на самом деле хранится в другой таблице:
posts = Post.objects.all()
post = posts[0]
author = post.author
print("Логин автора:", author.login)
print("Почта автора:", author.email)
print("День рождения автора:", author.birthday)
Один(автор) ко Многим(постам)
from django.db import models
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.SET_NULL)
...
Модель Post
from django.db import models
class User(models.Model):
login = models.CharField(max_length=200)
email = models.EmailField()
birthday = models.DateField()
avatar = models.ImageField()
...
Модель User
Один(автор) ко Многим(постам)
Например, мы хотим найти все статьи автора с логином voron434:
author = User.objects.filter(login="voron434")[0]
posts_by_this_author = Post.objects.filter(author=author)
По-хорошему, этот код следует упаковывать в один-единственный вызов filter:
author = Post.objects.filter(author__username="voron434")
from django.db import models
class Reporter(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
Создадим журналистов Джона и Пола
>>> reporter_1 = Reporter(first_name='John', last_name='Smith', email='john@example.com')
>>> reporter_1.save()
>>> reporter_2 = Reporter(first_name='Paul', last_name='Jones', email='paul@example.com')
>>> reporter_2.save()
Другой пример
class Article(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
from django.db import models
class Reporter(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
Другой пример
>>> from datetime import date
>>> article = Article(id=None, headline="This is a test", \
... pub_date=date(2005, 7, 27), reporter=reporter_1)
>>> article.save()
Создадим статью Джона вот так
class Article(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
А можно создать статью и так(через объект журналиста Джона)
>>> new_article = reporter_1.article_set.create(headline="John's second story", \
... pub_date=date(2005, 7, 29))
>>>
>>> new_article.reporter
<Reporter: John Smith>
>>> new_article2 = Article(headline="Paul's story", pub_date=date(2006, 1, 17))
>>> new_article2.save()
>>> reporter_2.article_set.add(new_article2)
>>> new_article2.reporter
<Reporter: Paul Jones>
А теперь создадим статью журналиста Пола
ДОДЕЛАТЬ
from django.db import models
class Reporter(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
Другой пример
>>> reporter_1.article_set.all()
[<Article: John's second story>, <Article: This is a test>]
Посмотрим, что есть у Джона
class Article(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
>>> reporter_2.article_set.all()
[<Article: Paul's story>]
И у Пола
>>> reporter_2.article_set.add(article)
>>> reporter_2.article_set.all()
[<Article: Paul's story>, <Article: This is a test>]
Добавим статью `article` к набору статей Пола и проверим, что она переместилась:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
text = models.TextField()
При работе с базами данных есть 4 базовые операции: создание (create), чтение (read), редактирование (update) и удаление (delete). Все 4 базовые функции называют коротко CRUD — по первым буквам каждой операции.
Модель Post
Read(чтение)
title = "CRUD"
crud_post = Post.objects.get(title=title)
Если поста с заголовком "CRUD" не окажется в базе, вы получите ошибку:
>>> models.DoesNotExist: Post matching query does not exist.
Это обычное исключение, его можно перехватить и обработать
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
text = models.TextField()
При работе с базами данных есть 4 базовые операции: создание (create), чтение (read), редактирование (update) и удаление (delete). Все 4 базовые функции называют коротко CRUD — по первым буквам каждой операции.
Модель Post
Create(создание)
Post.objects.create(title="Заголовок нового поста", text="Текст нового поста")
Пост создан и лежит в БД:
post = Post.objects.get(title="Заголовок нового поста")
print(post.title)
# Заголовок нового поста
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
text = models.TextField()
При работе с базами данных есть 4 базовые операции: создание (create), чтение (read), редактирование (update) и удаление (delete). Все 4 базовые функции называют коротко CRUD — по первым буквам каждой операции.
Модель Post
Update(редактирование)
post = Post.objects.get(title="Заголовок нового поста")
post.title = "От чего вымерли динозавры?"
post.save()
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
text = models.TextField()
При работе с базами данных есть 4 базовые операции: создание (create), чтение (read), редактирование (update) и удаление (delete). Все 4 базовые функции называют коротко CRUD — по первым буквам каждой операции.
Модель Post
Delete(удаление)
post = Post.objects.get(title="Новый заголовок")
post.delete() # Удалили пост из БД
Удаление отдельного поста:
Удаление целой выборки - Queryset:
all_posts = Post.objects.all()
all_posts.delete() # Удалили все посты из БД
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self): # __unicode__ on Python 2
return self.name
class Author(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
def __str__(self): # __unicode__ on Python 2
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog)
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
authors = models.ManyToManyField(Author)
n_comments = models.IntegerField()
n_pingbacks = models.IntegerField()
rating = models.IntegerField()
def __str__(self): # __unicode__ on Python 2
return self.headline
Возвращает количество записей в базе данных отвечающем запросу QuerySet.
Метод count() никогда не вызывает исключение.
# Returns the total number of entries in the database.
Entry.objects.count()
# Returns the number of entries whose headline contains 'Lennon'
Entry.objects.filter(headline__contains='Lennon').count()
Создано для онлайн-курса https://dvmn.org