# Повторение и подготовка --- ## Сппецификация для проекта ---- Мы напишем веб-приложение с именем Learning Log, при помощи которого пользователь сможет вести журнал интересующих его тем и создавать записи в журнале во время изучения каждой темы. Домашняя страница Learning Log содержит описание сайта и приглашает пользователя зарегистрироваться либо ввести свои учетные данные. После успешного входа пользователь получает возможность создавать новые темы, добавлять новые записи, читать и редактировать существующие записи. --- ## Подготовка сайта ---- Создайте для проекта новый каталог с именем learning_log, перейдите в этот каталог в терминальном режиме и создайте виртуальную среду следующими командами: ``` pip install pipenv pipenv shell pipenv install django ``` ---- Не выходя из активной виртуальной среды введите следующие команды для создания нового проекта: `django-admin startproject learning_log .` ---- Не забывайте про точку, иначе у вас могут возникнуть проблемы с конфигурацией при развертывании приложения. А если вы все же забыли, удалите созданные файлы и папки и снова выполните команду. ---- Введите следующую команду (все еще не покидая активную среду): `python manage.py migrate` ---- Убедимся в том, что проект был создан правильно. Введите команду runserver для просмотра текущего состояния проекта: `python manage.py runserver` ---- Если вы получаете сообщение об ошибке «Порт уже используется», прикажите Django использовать другой порт; для этого введите команду python `manage.py runserver 8001` и продолжайте перебирать номера портов по возрастанию, пока не найдете открытый порт. ---- Создайте приложение learning_logs: `python manage.py startapp learning_logs` --- ## База данных ---- Вот как выглядит модель тем обсуждения, которые будут сохраняться пользователями: ``` from django.db import models class Topic(models.Model): text = models.CharField(max_length=200) date_added = models.DateTimeField(auto_now_add=True) def __str__(self): return self.text ``` ---- Добавьте наше приложение в этот кортеж; измените содержимое INSTALLED_APPS, чтобы оно выглядело так: ``` INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'learning_logs', ) ``` ---- В терминальном окне введите следующую команду: `python manage.py makemigrations` ---- Теперь применим миграцию для автоматического изменения базы данных: `python manage.py migrate` --- ## Административная панель ---- Чтобы создать суперпользователя в Django, введите следующую команду и ответьте на запросы: `python manage.py createsuperuser` ---- Чтобы зарегистрировать Topic на административном сайте, введите следующую команду: ``` from .models import Topic admin.site.register(Topic) ``` ---- Код модели Entry (из файла models.py) выглядит так: ``` from django.db import models class Topic(models.Model): ... class Entry(models.Model): topic = models.ForeignKey(Topic, on_delete=models.CASCADE) text = models.TextField() date_added = models.DateTimeField(auto_now_add=True) class Meta: verbose_name_plural = 'entries' def __str__(self): return f"{self.text[:50]}..." ``` ---- Модель Entry тоже необходимо зарегистрировать. Файл admin.py должен выглядеть так: ``` from django.contrib import admin from .models import Topic, Entry admin.site.register(Topic) admin.site.register(Entry) ``` --- ## Маршрутизация ---- Добавим в файл URL-адреса приложения наш learning_logs: ``` from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('learning_logs.urls')), ] ``` ---- Создайте новый файл Python, сохраните его под именем urls.py в learning_logs и включите в него следующий код: ``` from django.urls import path from .import views app_name = 'learning_logs' urlpatterns = [ path('', views.index, name='index'), ] ``` --- ## Контроллеры ---- Откройте файл контроллера и добавьте следующий код домашней страницы: ``` from django.shortcuts import render def index(request): return render(request, 'learning_logs/index.html') ``` --- ## Шаблоны ---- В каталоге learning_logs создайте новый каталог с именем templates. В каталоге templates создайте другой каталог с именем learning_logs. Создайте index.html со следующим текстом: ``` <p>Learning Log</p> <p>Learning Log helps you keep track of your learning, for any topic you're learning about.</p> ``` ---- Вы можете получить следующее сообщение об ошибке: ModuleNotFoundError: No module named 'learning_logs.urls' В таком случае остановите сервер разработки нажатием клавиш Ctrl+C в терминальном окне, в котором была введена команда runserver. Затем снова введите команду python manage.py runserver. Каждый раз, когда вы сталкиваетесь с подобными ошибками, попробуйте остановить и перезапустить сервер. ---- Создайте base.html в одном каталоге с файлом index.html. Этот файл будет содержать элементы, общие для всех страниц; все остальные шаблоны наследуют от base.html. ``` <p> <a href="{% url 'learning_logs:index' %}">Learning Log</a> </p> {% block content %}{% endblock content %} ``` ---- Теперь нужно переписать файл index.html так, чтобы он наследовал от base.html. Обновленный файл index.html выглядит так: ``` {% extends "learning_logs/base.html" %} {% block content %} <p>Learning Log helps you keep track of your learning, for any topic you're learning about.</p> {% endblock content %} ``` ---- В больших проектах часто создается один родительский шаблон base.html для всего сайта и родительские шаблоны для каждого крупного раздела сайта. Все шаблоны разделов наследуют от base.html, и каждая страница сайта наследует от шаблона раздела. При такой структуре вы сможете легко изменять оформление и поведение сайта в целом, любого его раздела или отдельной страницы. ---- Изменения, которые следует внести в learning_logs/urls.py для создания нового адреса: ``` urlpatterns = [ path('', views.index, name='index'), path('topics/', views.topics, name='topics'), ] ``` ---- Контроллер topics() должна получать данные из базы данных и отправлять их шаблону. Обновленная версия views.py выглядит так: ``` from django.shortcuts import render from .models import Topic def index(request): ... def topics(request): topics = Topic.objects.order_by('date_added') context = {'topics': topics} return render(request, 'learning_logs/topics.html', context) ``` ---- Вывод списка тем в шаблоне осуществляется следующим образом: ``` {% extends "learning_logs/base.html" %} {% block content %} <p>Topics</p> <ul> {% for topic in topics %} <li>{{ topic }}</li> {% empty %} <li>No topics have been added yet.</li> {% endfor %} </ul> {% endblock content %} ``` ---- Затем необходимо изменить базовый шаблон и включить ссылку на страницу с темами. Добавьте следующий код в base.html: ``` <p> <a href="{% url 'learning_logs:index' %}">Learning Log</a> - <a href="{% url 'learning_logs:topics' %}">Topics</a> </p> {% block content %}{% endblock content %} ``` ---- Для создания параметрической ссылки нужно внести следующие изменения в learning_logs/urls.py: ``` urlpatterns = [ ... path('topics/<int:topic_id>/', views.topic, name='topic'), ] ``` ---- Контроллер topic() должна получить тему и все связанные с ней записи из базы данных: ``` def topic(request, topic_id): topic = Topic.objects.get(id=topic_id) entries = topic.entry_set.order_by('-date_added') context = {'topic': topic, 'entries': entries} return render(request, 'learning_logs/topic.html', context) ``` ---- Выражения в строках и, обращающиеся к базе данных за конкретной информацией, называются запросами. Когда вы пишете подобные запросы для своих проектов, сначала опробуйте их в оболочке Django. Вы сможете проверить результат намного быстрее, чем если напишете представление и шаблон, а затем проверите результаты в браузере. ---- шаблоне должно отображаться название темы и текст записей. Также необходимо сообщить пользователю, если по теме еще не было сделано ни одной записи: ``` {% extends 'learning_logs/base.html' %} {% block content %} <p>Topic: {{ topic }}</p> <p>Entries:</p> <ul> {% for entry in entries %} <li> <p>{{ entry.date_added|date:'M d, Y H:i' }}</p> <p>{{ entry.text|linebreaks }}</p> </li> {% empty %} <li>There are no entries for this topic yet.</li> {% endfor %} </ul> {% endblock content %} ``` ---- Прежде чем просматривать страницу отдельной темы в браузере, необходимо изменить шаблон списка тем, чтобы каждая тема вела на соответствующую страницу. Внесите следующие изменения в topics.html: ``` {% for topic in topics %} <li> <a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a> </li> {% empty %} ``` ---- Между topic.id и topic_id существует неочевидное, но важное различие. Выражение topic.id проверяет тему и получает значение соответствующего идентификатора. Переменная topic_id содержит ссылку на этот идентификатор в коде. Если вы столкнетесь с ошибками при работе с идентификаторами, убедитесь в том, что эти выражения используются правильно. --- ## Домашнее задание ---- Короткие записи: метод `__str__()` в модели Entry в настоящее время присоединяет многоточие к каждому экземпляру Entry, отображаемому Django на административном сайте или в оболочке. Добавьте в метод `__str__()` команду if, добавляющую многоточие только для записей, длина которых превышает 50 символов. Воспользуйтесь административным сайтом, чтобы ввести запись длиной менее 50 символов, и убедитесь в том, что при ее просмотре многоточие не отображается. ---- Django API: при написании кода для работы с данными проекта вы создаете запрос. Просмотрите документацию по созданию запросов к данным по адресу https://docs. djangoproject.com/en/3.2/topics/db/queries/. Многое из того, что вы увидите, покажется вам новым, но эта информация пригодится, когда вы начнете работать над собственными проектами. ---- Пиццерия: создайте новый проект с именем pizzeria, содержащий приложение pizzas. Определите модель Pizza с полем name, в котором хранятся названия видов пиццы (например, «Гавайская» или «Четыре сыра»). Определите модель Topping с полями pizza и name. Поле pizza должно содержать внешний ключ к модели Pizza, а поле name должно позволять хранить такие значения, как «ананас» или «грибы». Зарегистрируйте обе модели на административном сайте. Используйте сайт для ввода названий пиццы и топпингов. ---- План питания: представьте приложение для составления плана питания на неделю. Создайте новый каталог с именем meal_planner, а в этом каталоге — новый проект Django. Создайте новое приложение с именем meal_plans. Постройте простую домашнюю страницу для этого проекта. ---- Домашняя страница Pizzeria: добавьте домашнюю страницу в проект Pizzeria, который вы начали строить в упражнении 3 ---- Документация шаблонов: просмотрите документацию по шаблонам Django по адресу https://docs.djangoproject.com/en/3.2/ref/templates/. Используйте ее в работе над собственными проектами. ---- Страницы Pizzeria: добавьте страницу в проект Pizzeria из упражнения 3 с названиями видов пиццы. Свяжите каждое название пиццы со страницей, на которой выводится список дополнений к этой пицце. Обязательно примените наследование шаблонов, чтобы повысить эффективность построения страниц.
{"metaMigratedAt":"2023-06-16T12:34:45.478Z","metaMigratedFrom":"Content","title":"Повторение и подготовка","breaks":true,"contributors":"[{\"id\":\"0d39d5a3-691d-488c-8f1e-1a0fb0be4f13\",\"add\":11886,\"del\":199}]"}
    331 views