Команда курса благодарит Торжкова Максима Сергеевича за активное участие в подготовке данного руководства.
Для выполнения лабораторной работы потребуется PyCharm Professional
Лицензию можно получить через сайт JetBrains, указав бауманскую почту.
Также django-проект можно создать руками по этому тьюториалу
File -> New Project...
В меню New Project... выбираем Django, задаем путь к проекту в Location и задаем имя нашему приложению в Application name
В папке проекта bmstu
:
settings.py - настройки проекта, в проекте может быть несколько приложений
urls.py - соответствие урлам обработчиков(views).
В пакете bmstu_lab
:
views - обработчики приложения
templates - папка для шаблонов (html-файлы)
Нажимаем на кнопку Run в правом меню и запускаем приложение.
При этом в консоли должен вывестись трейс-лог о запуске приложения на localhost на порту :8000
По адресу http://127.0.0.1:8000/
в браузере должна показаться стандартная страница django-приложения.
views.py
from django.http import HttpResponse
def hello(request):
return HttpResponse('Hello world!')
urls.py
from bmstu_lab import views
urlpatterns = [
path('admin/', admin.site.urls),
path('hello/', views.hello),
]
После запуска сервера по пути http://127.0.0.1:8000/hello/
вы должны увидеть
Таким образом, код hello будет вызван при обращении к серверу по урлу /hello
Шаблоном является обычный текстовой файл, чаще всего html, который содержит в себе переменные и теги. Эти конструкции при отрисовке шаблона подменяются на данные, которые пользователь передает в качестве параметров шаблонизации. В конечном итоге у нас получается html-файл, который может быть показан в браузере пользователя.
Для начала будем отдавать пользователю статичную html-страницу, в ней не будет никаких конструкций шаблонизатора.
Создаем html-файл в директории ‘templates’.
index.html
<!doctype html>
<html lang="en" class="h-100">
<head>
<meta charset="utf-8">
<title>BMSTU</title>
</head>
<body>
Hello BMSTU students!
</body>
</html>
Чтобы вернуть пользователю созданный файл, используйте метод render.
Например данный код возвращает страницу index.html
, которая была создана в
папке templates.
views.py
def hello(request):
return render(request, 'index.html')
После запуска сервера по пути http://127.0.0.1:8000/hello/
вы должны увидеть
В шаблоне переменная имеет вид: {{ some_variable }}
. Когда шаблонизатор
рендерит страницу и находит переменную, то вместо нее он подставляет результат,
который вычисляется в этой переменной.
Добавим в статичную страницу переменные.
index.html
<!doctype html>
<html lang="en" class="h-100">
<head>
<meta charset="utf-8">
<title>BMSTU</title>
</head>
<body>
Hello BMSTU students!
Today is {{ current_date }}
</body>
</html>
Чтобы передать значение переменной из кода:
views.py
from datetime import date
def hello(request):
return render(request, 'index.html', {
'current_date': date.today()
})
Если значение переменной не было передано, то она будет заменена пустой строкой. В именах переменных не может быть пробелов или знаков препинания.
После запуска сервера по пути http://127.0.0.1:8000/hello/
вы должны увидеть
В качестве переменной может быть словарь, тогда к вложенным полям можно обращаться через точку.
def hello(request):
return render(request, 'index.html', { 'data' : {'current_date': date.today()}})
Today is {{ data.current_date }}
В шаблоне теги выглядят как {% tag %}
. С помощью тегов можно реализовывать
условия, циклы, свою логику. Большинство тегов должны закрываться:
{% tag %} content {% endtag %}
Допустим, нам нужно вывести список элементов. Для этого воспользуемся {% for %}
index.html
<!doctype html>
<html lang="en" class="h-100">
<head>
<meta charset="utf-8">
<title>BMSTU</title>
</head>
<body>
Hello BMSTU students!
Today is {{ data.current_date }}
<ul>
{% for var in data.list %}
<li>We like {{ var }}</li>
{% endfor %}
</ul>
</body>
</html>
views.py
from datetime import date
def hello(request):
return render(request, 'index.html', { 'data' : {
'current_date': date.today(),
'list': ['python', 'django', 'html']
}})
После запуска сервера по пути http://127.0.0.1:8000/hello/
вы должны увидеть
for итерируется по списку, доступ к элементам можно получать через
созданную переменную, в данном случае var
.
{% if variable %}
позволяет выводить содержимое блока, если значение переменной
“true” (или значение существует, либо если список и он не пустой)
Вместе с этим тегом можно использовать {% elif %}
, {% else %}
index.html
<ul>
{% for var in data.list %}
{% if var == 'python' %}
<li>We like {{ var }}</li>
{% elif var == 'django' %}
<li>We like {{ var }} a lot!</li>
{% else %}
<li>We do not like {{ var }}</li>
{% endif %}
{% endfor %}
</ul>
После запуска сервера по пути http://127.0.0.1:8000/hello/
вы должны увидеть
В теге if можно использовать:
- and
- or
- not
- операторы сравнения
- in (проверка что значение существует в списке)
Наследование шаблонов позволяет создать основной шаблон, который
содержит общие элементы, а частные места будут переопределять наследники.
Места, которые могут быть переопределены помечаются тегами {% block %}
Допустим, есть базовый шаблон base.html
:
base.html
<!doctype html>
<html lang="en" class="h-100">
<head>
<meta charset="utf-8">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
Hello BMSTU students!
{% block content %}{% endblock %}
</body>
</html>
Здесь определена часть, которая будет присутствовать у нас на каждой
странице, которая наследуется от него.
Создадим наследника orders.html
, который будет выводить список заказов:
orders.html
{% extends 'base.html' %}
{% block title %}Список заказов{% endblock %}
{% block content %}
<ul>
{% for order in data.orders %}
<li><a href="{% url 'order_url' order.id %}">{{ order.title }}</a> </li>
{% empty %}
<li>Список пуст</li>
{% endfor %}
</ul>
{% endblock %}
views.py
def GetOrders(request):
return render(request, 'orders.html', {'data' : {
'current_date': date.today(),
'orders': [
{'title': 'Книга с картинками', 'id': 1},
{'title': 'Бутылка с водой', 'id': 2},
{'title': 'Коврик для мышки', 'id': 3},
]
}})
Для каждого товара добавили ссылку на его отдельную с траницу в формате {% url 'order_url' order.id %}
В файле urls.py
необходимо определить url с именем ‘order_url’, который будет
принимать id заказа:
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.GetOrders),
path('order/<int:id>/', views.GetOrder, name='order_url'),
]
Создадим шаблон для страницы товара order.html
и ее view
order.html
{% extends 'base.html' %}
{% block title %}Заказ №{{ data.id }}{% endblock %}
{% block content %}
<div>Информация о заказе №{{ data.id }}</div>
{% endblock %}
views.py
def GetOrder(request, id):
return render(request, 'order.html', {'data' : {
'current_date': date.today(),
'id': id
}})
После запуска сервера по пути http://127.0.0.1:8000/
вы должны увидеть
По пути http://127.0.0.1:8000/order/2
вы должны увидеть
Позволяет рендерить в месте использования тега другой шаблон
orders.html
{% extends 'base.html' %}
{% block title %}Список заказов{% endblock %}
{% block content %}
<ul>
{% for order in data.orders %}
{% include 'order_element.html' with element=order %}
{% empty %}
<li>Список пуст</li>
{% endfor %}
</ul>
{% endblock %}
order_element.html
<li><a href="{% url 'order_url' element.id %}">{{ element.title }}</a> </li>
with - позволяет сменить контекст. Т.е. в шаблоне order_element.html
будут доступны не только order, orders , но и element
В settings.py
указан путь до статических файлов
STATIC_URL = '/static/'
В приложении создаем папку и кладем туда файлы:
Файлы .css
кладем в отдельную папку static/css
Перед использованием ссылки на статический файл, в шаблоне:
{% load static %}
Используем ссылку:
<link rel="stylesheet" type="text/css" href="{% static 'css/examp.css' %}">
Пример .css
.order-text {
font-size: 40px;
}
Пример шаблона с css
<div class="order-text">Информация о заказе №{{ data.id }}</div>
Для передачи данных из браузера на сервер Django, необходимо добавить форму, кнопку и поле ввода в наш шаблон
<form action="sendText" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input name="text" type="text"><br><br>
<input type="submit" value="Submit" >
</form>
Добавить в urls.py
обработчик нашего POST-запроса views.sendText
для url /sendText
path('sendText', views.sendText, name='sendText'),
А в обработчик sendText
в views.py
добавляем код получения значения передаваемого параметра из POST-запроса
def sendText(request):
input_text = request.POST['text']
...