Topic 2 of 6

Course materials are currently available in Russian only.

Адреса и представления

Django — фреймворк «всё включено»: в нём уже есть работа с базой данных, шаблоны, формы, авторизация и админ-панель. На Django сделаны Instagram, Pinterest, Mozilla и тысячи других сайтов.

В курсе вы соберёте блог с комментариями: адреса, страницы, посты в базе, комментарии и форму.

Проект в одном файле

Обычный проект Django — это папка с десятком файлов, которую создаёт команда django-admin startproject. Чтобы не отвлекаться, в задачах курса весь проект умещается в один файл:

import django
from django.conf import settings

settings.configure(DEBUG=True, SECRET_KEY="dev-only", ALLOWED_HOSTS=["*"], ROOT_URLCONF=__name__)
django.setup()

from django.http import HttpResponse
from django.urls import path


def index(request):
    return HttpResponse("Привет, это мой блог!")


urlpatterns = [path("", index)]

if __name__ == "__main__":
    from django.core.management import execute_from_command_line
    execute_from_command_line(["manage.py", "runserver", "--noreload"])
  • settings.configure(...) — настройки (в большом проекте они лежат в settings.py); ROOT_URLCONF говорит, где искать адреса — здесь в этом же файле;
  • django.setup() нужно вызвать до импорта остальных частей Django;
  • runserver запускает сервер разработки на http://127.0.0.1:8000/.

Адреса

urlpatterns = [
    path("", index, name="index"),
    path("posts/", post_list, name="post-list"),
    path("posts/<int:pk>/", post_detail, name="post-detail"),
]
  • адреса пишутся без косой черты в начале и, по традиции Django, с косой чертой в конце;
  • <int:pk> — часть адреса становится аргументом pk (уже числом). Конвертеры: str (по умолчанию), int, slug (буквы, цифры, -, _), path;
  • Django проверяет адреса по порядку и берёт первый подходящий — более общие шаблоны ставьте ниже;
  • name — имя адреса. reverse("post-detail", args=[5]) строит /posts/5/, а в шаблонах — {% url "post-detail" 5 %}.

Представления

from django.http import HttpResponse, JsonResponse, Http404


def post_detail(request, pk):
    if pk not in POSTS:
        raise Http404("Нет такого поста")
    return HttpResponse(POSTS[pk])


def search(request):
    q = request.GET.get("q", "")
    return JsonResponse({"q": q})

Представление получает request и возвращает ответ: HttpResponse (текст или HTML), JsonResponse (JSON), redirect(...). Код ответа — status=. raise Http404 из любого места отдаёт страницу 404.

Из request берут всё о запросе: request.GET — параметры после ?, request.POST — поля формы, request.method.

Как проверяются задачи

Проверка открывает адреса тест-клиентом Django (django.test.Client) — без сервера. «Запустить у себя» поднимает runserver, и блог можно открыть в браузере.

Итог

  • проект в одном файле: settings.configure, django.setup(), urlpatterns;
  • path("posts/<int:pk>/", view, name="…"), порядок важен;
  • HttpResponse, JsonResponse, Http404, request.GET;
  • reverse строит адрес по имени.