Мы напишем веб-приложение с именем 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 с названиями видов пиццы. Свяжите каждое название пиццы со страницей, на которой выводится список дополнений к этой пицце. Обязательно примените наследование шаблонов, чтобы повысить эффективность построения страниц.