Добавление главной страницы
Начальный курс по Django дал вам представление о том, как работает URL Mapping и Views.
Перечень правил, связывающих URL сайта с view-функциями, содержится в списке urlpatterns. В каждом элементе вызывается специальная функция path(). Вот знакомый вам пример urlpatterns:
Скопировать кодPYTHON
urlpatterns = [
path('', views.index),
path('accounts/sign-up', acc_views.sign_up),
path('accounts/sign-in', acc_views.sign_in),
path('accounts/my-account', acc_views.my_account, name='account'),
]
Функция path() принимает такие параметры: path(route, view, name)
- route — шаблон веб-адреса (URL). Получив HTTP-запрос, Django идет по списку
urlpatterns сверху вниз, пока не найдёт совпадение запрошенного адреса с route в одном из вызовов path(). Если нет ни одного совпадения, пользователю вернётся сообщение об ошибке 404: «Страница не найдена». - view — это имя view-функции. Если Django найдёт совпадение с шаблоном, то перенаправит вызов в указанную view-функцию.
- name — имя для
path(), к нему можно обратиться из кода, чтобы установить ссылку на страницу сайта.
Есть и дополнительные параметры функции
path(), о которых можно прочесть в
документации.
Генератор проекта создал главный файл yatube/urls.py, но в нём будут только ссылки на urls.py приложений нашего проекта.
Создадим шаблон адреса главной страницы в urls.py приложения Posts и напишем view-функцию для обработки запроса к этой странице.
В приложении Posts создайте файл posts/urls.py и добавьте в него код:
Скопировать кодPYTHON
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index")
]
В головной файл yatube/urls.py добавьте импорт правил из нового файла:
Скопировать кодPYTHON
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path("", include("posts.urls")),
path("admin/", admin.site.urls),
]
Запросы к БД можно делать прямо из кода Python, для этого в Django ORM есть специальный синтаксис. Вместо того чтобы писать громоздкие запросы, можно одной строкой получить информацию из базы данных.
В файл posts/views.py добавьте views-функцию index:
Скопировать кодPYTHON
from django.http import HttpResponse
from .models import Post
def index(request):
latest = Post.objects.order_by('-pub_date')[:10]
output = []
for item in latest:
output.append(item.text)
return HttpResponse('\n'.join(output))
Вы справились с уроком по SQL, так что и без объяснений разберётесь, какие операции совершает функция index. Тут несколько правильных ответов, выбирайте.
В функции index переменная latest получает выборку записей модели Post из БД. После имени модели и специальной точки входа .objects указаны условия запроса.
В запросе мы:
- сортируем записи по свойству
pub_date по убыванию, от больших значений к меньшим (об этом говорит знак -), то есть новые записи оказываются вверху выборки - забираем только первые 10 элементов из полученного списка
Конструкция написана на безупречном языке Python.
Механизм Django ORM переводит её на SQL:
Скопировать кодSQL
SELECT
'posts_post'.'id',
'posts_post'.'text',
'posts_post'.'pub_date',
'posts_post'.'author_id'
FROM
'posts_post'
ORDER BY
'posts_post'.'pub_date' DESC
LIMIT 10
Полученные записи передаются в код как объекты класса Post и в виде списка сохраняются в переменной latest. Мы проходим по ним циклом, из каждого объекта достаём значение свойства text и добавляем тексты постов в список output. Затем возвращаем строку, собранную из элементов этого списка. Это и есть наш ответ на HTTP-запрос.
Определенно, это тот же самый текст, что и в админ-зоне. Выглядит не очень, но вы уже сделали большой шаг вперёд: вывели текст из базы данных на главную страницу блога.
Вот ещё несколько примеров, как можно получить данные из базы:
Post.objects.all() — получить все записи модели PostPost.objects.get(id=1) — получить запись модели Post, у которой значение поля id равно 1. Поскольку поле id — это первичный ключ, а Django автоматически создаёт у модели свойство pk, то альтернативная запись этого же запроса будет такой: Post.objects.get(pk=1).Post.objects.filter(pub_date__year=1854) — запрос вернёт объекты, у которых значение года в поле pub_date равно 1854. Обратите внимание на синтаксис фильтрации: двойное нижнее подчёркивание между названиями поля и фильтра. Подробнее о функции filter() — в документации.Post.objects.filter(text__startswith="Писать не хочется") — пример фильтра по текстовому полю, он вернёт записи, начинающиеся с указанной в фильтре строки.