Skip to content

Latest commit

 

History

History
510 lines (375 loc) · 17.8 KB

lab1_tutorial.md

File metadata and controls

510 lines (375 loc) · 17.8 KB

Методические указания по выполнению лабораторной работы №1

Для выполнения лабораторной работы потребуется VS Code или PyCharm Professional

Создание проекта локально

Пример для PyCharm
File -> New Project...
В меню New Project... выбираем Django, задаем путь к проекту в Location и задаем имя нашему приложению в Application name

Создание проекта

Создание проекта на виртуальной машине (удаленно)

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

  • Открываем VS Code и устанавливаем расширение Remote Development

Подключение к удаленному хосут

ВНИМАНИЕ! На этом шаге у вас уже должна быть запущена виртуальная машина!

  • После установки расширения появится такой значок в левом нижнем углу, нажимаем на него

Подключение к удаленному хосут

  • Выбираем пункт Connect to Host...

Как посмотреть IP виртуальной машины:
Вводим команду - ifconfig на ВМ, находим интерфейс Ethernet, в данном случае - enp0s3 м смотрим ip на второй строке, напротив inet
Обратите внимание, что в настройках "Сеть" виртуальной машины тип подключения выставлен на - "Сетевой мост" \

IP

Тип подключения

  • Строка подключния будет иметь такой вид - user_name@remote_host_ip

Строка подключения

  • Следующим шагом необходимо выбрать, где будет размещаться ваш проект. Рекомендую для проектов создать отдельную директорию, например, как у меня - pythonProjects

Директория с проектами

  • Нажимаем ОК и вводим пароль
  • Если подключние прошло удачно, то видим следующее

Удачное подключение

Создаем проект Django

  • Создаем папку с желаемым названием проекта и переходим в нее

Создание папки для проекта

  • Создаем виртуальное окружение с помощью утилиты venv и активируем его

Виртуальное окружение

  • После активации виртуального окружения уставанвливаем Django (на момент написания методички актуальная версия - 4.2.4)

Установка Django

  • Создаем проект с помощью Django комндой - django-admin startproject <your_project_name> .

Создание проекта Django

  • После создания проекта переходим в файл settings.py и в ALLOWED_HOSTS добавляем звездочку

  • Запускаем проект командой - python manage.py runserver 0.0.0.0:8000 ВНИМАНИЕ! Чтобы сревис был доступен с домашней ОС - обязательно надо запускать на широковещательном адресе 0.0.0.0. Порт может быть любой, в данном случае - 8000

  • Делаем запрос с домашней ОС, для этого вводим в браузере адрес ВМ + порт: который указали при запуске проекта

Остальная работа выполняется точно также, как и на основной машине.

Структура проекта

В папке проекта bmstu:
settings.py - настройки проекта, в проекте может быть несколько приложений
urls.py - соответствие урлам обработчиков(views).

В пакете bmstu_lab:
views - обработчики приложения

templates - папка для шаблонов (html-файлы)

Структура проекта

Запуск приложения

Нажимаем на кнопку Run в правом меню и запускаем приложение.

Запуск

При этом в консоли должен вывестись трейс-лог о запуске приложения на localhost на порту :8000

Консоль

По адресу http://127.0.0.1:8000/ в браузере должна показаться стандартная страница django-приложения.

Браузер

Как работать с View и Urls

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>

Чтобы указать Django на то, где искать наши шаблоны проверьте файл settings.py. В нем в переменной TEMPLATES в поле DIRS должен быть указан путь к вашим шаблонам

TEMPLATES = [
    {
        # ...
        "DIRS": [BASE_DIR / "bmstu_lab/templates"],
        # ...
    },
]

Чтобы вернуть пользователю созданный файл, используйте метод render. Например данный код возвращает страницу index.html, которая была создана в папке templates.

views.py

from django.shortcuts import render

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 вы должны увидеть

Привет студенты!

Include в шаблонизации

Позволяет рендерить в месте использования тега другой шаблон

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 = '/bmstu_lab/static/'
STATICFILES_DIRS = [
    BASE_DIR / "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>

Получение данных из запроса, input

Для передачи данных из браузера на сервер 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']
    ...