bash
... System check identified no issues (0 silenced). September 22, 2016 - 16:11:26 Django version 1.10, using settings 'locallibrary.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK.
Когда сервер запустится, вы сможете посетить сайт по адресу http://127.0.0.1:8000/ в вашем веб-браузере. Вы должны увидеть страницу с ошибкой, навроде этой:
Не волнуйтесь! Эта страница должна появиться и сообщить нам, что мы ещё не настроили ни одной страницы в модуле catalogs.urls (на который мы были перенаправлены запросили корневой URL сайта).
Примечание: Показанная выше страница открывает нам одно из замечательных свойств Django — автоматические отчёты об ошибках. На экране с ошибкой отображается множество полезной информации, когда страница не найдена, или ошибка была вызвана кодом. В данном случае, мы видим, что запрошенный URL не соответствует ни одному шаблону (из указанных). Подобные отчёты будут выключены при DEBUG=False (когда мы разместим приложение в Сеть), в этом случае будет показана менее информативная, но более дружелюбная к пользователю страница(которую вам надо будет создать - прим. переводчика).
На данном этапе, мы поняли, что Django работает должным образом!
Примечание: вам следует перезапускать миграцию и заново тестировать сайт, после того как вы делаете важные изменения. Поверьте, это не займёт много времени!
Домашнее задание
Папка catalog/ содержит файлы контроллеров(views), моделей(models), и других частей приложения. Просмотрите эти файлы.
Как было написано выше, URL соотноситель для админ-панели был подключён в файле urls.py. Войдите в административную часть и посмотрите, что произойдёт (вы можете найти URL из соотношения выше).
Подводя итоги
Теперь вы создали полноценный скелет веб-приложения, который теперь вы можете расширить url соотносителями, контроллерами(views) и моделями(models).
Теперь скелет Сайта местной библиотеки сделан и запущен, теперь самое время начать писать код, который научит сайт делать то, что он должен делать.
Также посмотрите эти статьи
- Пишем своё первое приложение на Django - часть 1 (документация Django)
- Приложения (документация Django). содержит информацию о настройке приложений.
- Назад
- Обзор: Django
- Далее
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 3 авг. 2023 г. by MDN contributors.
Your blueprint for a better internet.
# Создание сайта на Django
Django — фрэймворк для создания сложных и комплексных сайтов на языке Python.
В этой статье на примере создания сайта, показывающего погоду в разных городах мира, мы продемонстрируем работу с API, HTML-шаблонами и базами данных в Django.
Запускать проект будем на Джино.Хостинге.
# Подготовка к работе
Создадим для нашего сайта новый хостинг-контейнер. Для этого в разделе Аккаунт
Хостинг выберем «Создать новый хостинг». После создания перейдём в раздел «Услуги» и подключим «Поддержку скриптовых языков» и «Поддержку SSH».
После подключения выбранных услуг подключимся к хостингу по SSH. Данные для SSH-подключения указаны в разделе Управление
Перед первым подключением к хостинг-контейнеру в разделе Управление
Настройки SSH нужно задать пароль пользователя. Порт для подключения используется стандартный — 22.
Также в этом разделе можно настроить ограничение доступа к хостингу только с указанных IP-адресов.
После подключения к хостингу по SSH создадим виртуальное окружение для Python:
/opt/alt/python37/bin/virtualenv --python /opt/alt/python310/bin/python3 weather_venv
Эта команда создаёт виртуальное окружение weather_venv для Python 3.10. Список всех доступных версий Python и пути к их интерпретаторам указаны в разделе Управление
После создания виртуального окружения активируем его
source ./weather_venv/bin/activate
и установим Django с помощью стандартного пакетного менеджера
pip install django
Теперь наше виртуальное окружение готово к работе. Перейдём к созданию проекта.
# Создание и запуск проекта
Создавать новый проект будем на локальной машине с последующим деплоем проекта на Хостинг. О том, как подготовить Хостинг к развёртыванию нового проекта и о способах загрузки проекта на сервер можно прочитать в нашей инструкции по развёртыванию проекта на Джино.Хостинге.
Создадим новый проект Django:
django-admin startproject weather_project
Эта команда создаст папку weather_project со вложенной одноимённой папкой weather_project и файлом manage.py, отвечающим за управление проектом.
Уже на данном этапе можно настроить загрузку проекта на сервер и проверить работу пустого Django-проекта. Поскольку наше приложение будет объёмным и в течение работы мы будем несоклько раз обновлять его и изменять, рекомендуем само приложение создавать в IDE VSCode или PyCharm, из которых удобно настроить выгрузку приложения непосредственно на сервер.
После загрузки проекта на хостинг в папку с доменным именем, на котором он будет работать, проверим его работу.
Для запуска Django-проекта на Хостинге нужно создать файл passenger_wsgi.py, который будет отвечать за связь проекта с веб-сервером. Содержимое файла должно быть следующим:
import sys, os INTERP = os.path.expanduser("~/weather_venv/bin/python3") if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv) from weather_project.wsgi import application
Здесь ~/weather_venv/bin/python3 — путь к виртуальному окружению на хостинге; weather_project.wsgi — указание на основной файл, который будет запускать приложение.
Теперь нужно изменить настройки самого нашего проекта, чтобы он мог запускаться на выбранном домене. Для этого в папке weather_project откроем файл settings.py и в строке ALLOWED_HOSTS укажем выбранное доменное имя, например ALLOWED_HOSTS = [ example.com ] .
После этого в разделе Управление
Настройки веб-сервера для выбранного домена укажем версию Python, которая будет использоваться для работы сайта и нажмём Перезагрузить , чтобы перезагрузить веб-сервер и проверить работу нашего проекта.
В адресной строке браузера укажем наше доменное имя. Если всё работает правильно, мы увидим стандартную стартовую страницу Django
# Создание приложения
Вернёмся к нашей IDE и создадим приложение в нашем проекте:
django-admin startapp weather_app
Эта команда создаст папку weather_app, в которой уже находятся шаблоны для создания основных файлов нашего приложения.
Теперь перейдём в папку weather_app и создадим здесь файл urls.py:
from django.urls import path urlpatterns = [ ]
Этот файл дублирует файл urls.py всего проекта. Основное отличие его в том, что в этом файле будут только те URL, которые относятся к нашему приложению, а не ко всему проекту в целом.
Чтобы добавить наше приложение к проекту, добавим его название в список уже установленных приложений проекта. Для этого в папке weather_project откроем файл settings.py и в блок INSTALLED_APPS добавим название нашего приложения:
… INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'weather_app', ] …
Теперь изменим основной файл urls.py, находящийся в папке weather_project. Мы добавим к нему строку, указывающую на использование нашего нового файла urls.py:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('weather.urls')), ]
# Создание HTML-шаблона
Следующим шагом нам нужно создать HTML-шаблон, в который будут экспортироваться полученные по API данные и отображаться на главной странице нашего сайта.
Создадим в папке нашего приложения weather_app папку для шаблонов templates. В папке templates создадим папку для шаблонов приложения weather и уже в этой папке создадим файл index.html.
Содержимое индексного файла ( ~/domains/example.com/weather_app/templates/weather/index.html ) будет следующим:
DOCTYPE html> html lang="en"> head> meta charset="UTF-8"> meta name="viewport" content="width=device-width, initial-scale=1.0"> meta http-equiv="X-UA-Compatible" content="ie=edge"> title>What's the weather like?title> link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.2/css/bulma.css" /> head> body> section class="hero is-primary"> div class="hero-body"> div class="container"> h1 class="title"> What's the weather like? h1> div> div> section> section class="section"> div class="container"> div class="columns"> div class="column is-offset-4 is-4"> form method="POST"> div class="field has-addons"> div class="control is-expanded"> input class="input" type="text" placeholder="City Name"> div> div class="control"> button class="button is-info"> Add City button> div> div> form> div> div> div> section> section class="section"> div class="container"> div class="columns"> div class="column is-offset-4 is-4"> div class="box"> article class="media"> div class="media-left"> figure class="image is-50x50"> img src="http://openweathermap.org/img/w/10d.png" alt="Image"> figure> div> div class="media-content"> div class="content"> p> span class="title">Sun Cityspan> br> span class="subtitle">59° Fspan> br> Solar wind with some prominence p> div> div> article> div> div> div> div> section> footer class="footer"> footer> body> html>
В Django-проекте основное взаимодействие происходит между файлами views.py приложения и urls.py проекта. Теперь, когда шаблон готов, изменим эти файлы для запуска приложения.
Откроем файл views.py и приведём его к следующему виду:
from django.shortcuts import render def index(request): return render(request, 'weather/index.html') #returns the index.html template
Здесь мы назвали наш основной запрос index и использовали функцию render для обращения к файлу шаблона. Теперь добавим url, который будет отправлять запрос к этому шаблону. Откроем файл urls.py, который мы создали в папке с нашим приложением и приведём его к следующему виду:
from django.urls import path from . import views urlpatterns = [ path('', views.index), #the path for our index view ]
Здесь описано перенаправление запроса к файлу views.py, который мы только что изменили.
Проверим работу нашего приложения! Загрузим его на сервер и перезагрузим веб-сервер ( Управление
Настройки веб-сервера ). Откроем браузер и проверим страницу нашего сайта:
# API
Для работы нашего приложения, нам будут нужны актуальные данные о погоде в разных городах мира. Получать их мы будем от одного из свободных погодных сервисов — Open Weather Map
Для получения данных по API нам нужно зарегистрироваться на сайте и в личном кабинете получить уникальный ключ, которым будем подписывать запрос
Чтобы проверить работу полученного ключа, можно через бразуер отправить запрос к приложению в следующем формате:
http://api.openweathermap.org/data/2.5/weather?q=Penza&units=imperial&appid=ваш_API_ключ
В ответ в браузере должна появиться информация в JSON-формате:
"coord":"lon":45.0046,"lat":53.2007>,"weather":["id":800,"main":"Clear","description":"clear sky","icon":"01d">],"base":"stations","main":"temp":56.82,"feels_like":54.61,"temp_min":56.82,"temp_max":56.82,"pressure":1009,"humidity":51>,"visibility":10000,"wind":"speed":5.3,"deg":174,"gust":8.41>,"clouds":"all":0>,"dt":1652067877,"sys":"type":2,"id":219846,"country":"RU","sunrise":1652058692,"sunset":1652114482>,"timezone":10800,"id":511565,"name":"Penza","cod":200>
Из этого объёма нам будут нужны только основные сведения. Для этого наше приложение будет конвертировать JSON-формат в формат данных, воспринимаемых Python.
Настроим работу запросов и конвертирование полученные данных из JSON-формата в формат данных Python. Для этого добавим в файл views.py строки import requests , url , city , city_weather :
from django.shortcuts import render import requests def index(request): url = 'http://api.openweathermap.org/data/2.5/weather?q=<>&units=imperial&appid=ваш_API_ключ' city = 'Penza' city_weather = requests.get(url.format(city)).json() return render(request, 'weather/index.html')
Мы добавили URL, к которому будем отправлять запрос и строку, отвечающую за конвертирование данных из JSON в Python-формат.
В нашем случае в URL не указан город, город указан отдельно в строке city и сейчас это Penza. Позже мы исправим это и будем указывать город в базе данных и через специальную форму ввода в самом приложении.
Сейчас, когда наше приложение отправляет запрос и получает ответ, можно перейти к отображению полученных данных на нашем сайте.
# Отправка данных в шаблон
Чтобы отобразить полученные данные на странице сайта, нужно передать их в index.html. Для этого создадим библиотеку значений, данные из которой и будем передавать в шаблон.
В файле views.py добавим следующие строки:
... def index(request): ... weather = 'city' : city, 'temperature' : city_weather['main']['temp'], 'description' : city_weather['weather'][0]['description'], 'icon' : city_weather['weather'][0]['icon'] > return render(request, 'weather/index.html') #returns the index.html template
Здесь мы добавили блок weather=<> , в котором определили переменные city , temperarute , description и icon . Этим переменным мы присвоили определённые значения из получаемого по API массива данных.
Теперь, чтобы передать эти данные в шаблон создадим дополнительную переменную context , которая и будет передавать все данные в шаблон. Здесь же, в файле views.py добавим строки:
... def index(request): ... context = 'weather' : weather> return render(request, 'weather/index.html', context) #returns the index.html template
Переменная context - это словарь, в котором содержатся все данные блока weather .
Теперь нужно настроить отображение получаемых данных в самом HTML-шаблоне. Откроем файл index.html и вместо значений, которые на предыдущем шаге задавали вручную вставим значения наших новых переменных, используя
. div class="box"> article class="media"> div class="media-left"> figure class="image is-50x50"> img src="http://openweathermap.org/img/w/>.png" alt="Image"> figure> div> div class="media-content"> div class="content"> p> span class="title">>span> br> span class="subtitle">>° Fspan> br> > p> div> div> article> div> .
В данном случае важно помнить, что при вызове переменной из словаря нужно использовать . , а не стандартный синтаксис Python (например, вызов переменной city будет выглядеть как weather.city вместо привычного weather[‘city’] .
После внесения необходимых изменений снова обновим наше приложение на сервере и на главной странице нашего сайта увидим, что информация о погоде в указанном городе получена.
Следующая «проблема» нашего приложения — указание города. В данном случае он указан напрямую в коде. Это неправильно — сделаем так, чтобы список городов, для которых нужно отображать информацию, хранился в базе данных.
Воспользуемся для хранения списка городов SQLite, идущей в составе Django. Чтобы добавить города в базу, создадим дополнительную форму в окне администратора приложения.
# Администрирование приложения
Создадим администратора нашего приложения командой:
python manage.py createsuperuser
Эта команда запустит процесс создания администратора нашего сайта, в ходе которого мы укажем его основные данные: пароль, адрес электронной почты и т.д.
После создания администратора, вход в панель администрирования осуществляется через браузер по адресу http://your_domain/admin .
Теперь добавим в список доступных администратору операций возможность создавать список городов. Для этого воспользуемся файлом models.py, который находится в папке нашего приложения. Приведём этот файл к следующему виду:
from django.db import models class City(models.Model): name = models.CharField(max_length=25) def __str__(self): #show the actual city name on the dashboard return self.name class Meta: #show the plural of city as cities instead of cities verbose_name_plural = 'cities'
Эта директива создаст в базе данных приложения таблицу из одной колонки, которая будет называться «name» и в которой будут храниться названия городов.
Чтобы создать эту таблицу в базе, нужно создать связи командой makemigrations и затем на основании этих связей обновить содержимое приложения:
python manage.py makemigrations python manage.py migrate
Таблица в базе создана и готова к заполнению. Чтобы заполнить её, добавим форму ввода города в панель администрирования. Изменим для этого файл admin.py нашего приложения. Привдём его к следующем виду:
from django.contrib import admin from .models import City admin.site.register(City)
Теперь в панели администрирования появилась новая форма для ввода городов. Добавим несколько.
# Добавление городов на главную страницу сайта
После того, как мы добавили в базу список городов, нам нужно изменить файлы views.py и index.html, чтобы на главной странице нашего сайта отображались все города.
Начнём с изменения файла views.py. Импортируем столбец City и сделаем отдельный запрос по API для каждого из городов:
from django.shortcuts import render import requests from .models import City def index(request): url = 'http://api.openweathermap.org/data/2.5/weather?q=<>&units=imperial&appid=ваш_API_ключ' cities = City.objects.all() #return all the cities in the database ...
Теперь нам нужно сохранить данные для каждого города из списка и передать их в HTML-шаблон. Для этого создадим отдельный список weather_data , в котором будут храниться данные для каждого города.
Затем заменим переменную City на cities .
После — добавим словарь weather для каждого города в общий список weather_data и в конце немного изменим context , чтобы он передавал весь список в HTML-шаблон, а не только один блок данных.
В итоге файл views.py должен прийти к такому виду:
... def index(request): ... cities = City.objects.all() #return all the cities in the database weather_data = [] for city in cities: city_weather = requests.get(url.format(city)).json() #request the API data and convert the JSON to Python data types weather = 'city' : city, 'temperature' : city_weather['main']['temp'], 'description' : city_weather['weather'][0]['description'], 'icon' : city_weather['weather'][0]['icon'] > weather_data.append(weather) #add the data for the current city into our list context = 'weather_data' : weather_data> return render(request, 'weather/index.html', context) #returns the index.html template
Далее, изменим index.html — добавим цикл в отображение данных в шаблоне. Для этого добавим строки и в начало и конец отображения данных о городах. В итоге, блок отображения данных должен стать таким:
. div class="column is-offset-4 is-4"> div class="box"> article class="media"> div class="media-left"> figure class="image is-50x50"> img src="http://openweathermap.org/img/w/>.png" alt="Image"> figure> div> div class="media-content"> div class="content"> p> span class="title">>span> br> span class="subtitle">>° Fspan> br> > p> div> div> article> div> div> .
Теперь можно проверить, что у нас получилось. В адресной строке браузера адрес нашего сайта. В зависимости от добавленных в список городов, главная страница сайта должна выглядеть примерно так:
# Создание формы ввода
Последним, что осталось сделать для нашего сайта — создать форму ввода, чтобы пользователи могли добавлять города прямо с главной страницы сайта.
Для этого создадим новый файл forms.py в папке нашего приложения. Содержимое файла будет следующим:
from django.forms import ModelForm, TextInput from .models import City class CityForm(ModelForm): class Meta: model = City fields = ['name'] widgets = 'name': TextInput(attrs='class' : 'input', 'placeholder' : 'City Name'>), > #updates the input class to have the correct Bulma class and placeholder
Это форма ввода нового имени города. Чтобы она заработала, нужно добавить её описание во views.py и передать данные из неё в шаблон.
Начнём с изменений во views.py
... from .forms import CityForm def index(request): ... form = CityForm() weather_data = [] ... context = 'weather_data' : weather_data, 'form' : form>
Мы добавили описание передачи данных из формы и описали саму форму ввода данных.
Теперь изменим index.html
. form method="POST"> div class="field has-addons"> div class="control is-expanded"> > div> div class="control"> button class="button is-info"> Add City button> div> div> form> .
В индексный файл мы добавили блок описания формы и CSRF-токен, необходимый для отправки запросов из Django.
После описания формы ввода в шаблоне, нам нужно проверить добавить во views.py блок, который будет отвечать за обработку запросов, отправленных в форме:
... def index(request): url = 'http://api.openweathermap.org/data/2.5/weather?q=<>&units=imperial&appid=ваш_API_ключ' cities = City.objects.all() #return all the cities in the database if request.method == 'POST': # only true if form is submitted form = CityForm(request.POST) # add actual request data to form for processing form.save() # will validate and save if validate form = CityForm() ...
Здесь мы добавили if для проверки наличия запроса, отправленного из HTML-шаблона. Далее полученные данные сохраняются и передаются в обработку.
Сохраните все сделанные изменения и перезагрузите веб-сервер. Теперь можно проверять работу формы для добавления городов. Добавим, например, «Sydney»:
# Заключение
Мы описали создание сайта на Django с использованием HTML-шаблонов, запросов по API, баз данных и формой для добавления информации в базу данных.
© Джино, 2003–2022. «Джино» является зарегистрированным товарным знаком.
Лицензия на телематические услуги связи №150549 от 09.03.2017.
Создаём первое веб-приложение с Джанго
Мы создадим веб-приложение на Django, у которого будет панель администратора, загрузка закладок, а пользователи смогут отвечать на них.
Напишем простое веб-приложение на Django.
Джанго — это Open Source фреймворк для создания веб-приложений различной сложности на Python. Одним из его основных преимуществ является то, что вам нужно позаботиться только о логике будущего веб-приложения, остальное сделает Django.
Мы создадим приложение, у которого будет панель администратора и возможность загружать загадки, а у пользователей, соответственно, возможность отвечать на них. Во время разработки будут использоваться Python 3.4.3 и Django 1.9.1.
Устанавливаем Django
Делается это очень просто, в командной строке нужно написать: pip install Django==1.9.1 .
Создаём проект
Если вы правильно установили Django, то после запуска django-admin --version вы увидите текущую версию фреймворка. Теперь создадим проект. Это можно сделать следующим образом: django-admin startproject django_example .
Как только создание проекта будет завершено, взглянем на директорию нашего проекта:
- django_example/__init__.py — пустой файл, который говорит Python, что данная директория должна восприниматься в качестве пакета.
- django_example/settings.py содержит конфигурацию нашего проекта.
- django_example/urls.py — здесь объявляются URL.
- django_example/wsgi.py — с помощью него приложение может работать с веб-сервером по протоколу WSGI.
- manage.py позволяет взаимодействовать с проектом.
Теперь пришло время запустить наше приложение. Для этого в командной строке нужно написать python manage.py runserver . После этого в адресной строке браузера нужно написать: http://127.0.0.1:8000/ . Если вы увидели «You have unapplied migrations; your app may not work properly until they are applied.», то не волнуйтесь, мы вернемся к этому чуть позже.
Пишем веб-приложение на Django
Определим различие между проектом и приложением. Приложение — это программа, которая что-то делает, а проект — это группа приложений.
Итак, приступим к созданию приложения. Это делается следующим образом: python manage.py startapp riddles .
Как только создано веб-приложение, напишем вид, по правилам Джанго все виды должны храниться в файле views.py .
from django.http import HttpResponse def index(request): return HttpResponse("Hello, World!")
Теперь, чтобы привязать наш вид к URL, создадим файл urls.py .
from django.conf.urls import url from . import views app_name = 'riddles' urlpatterns = [ url(r'^$', views.index, name='index'), ]
В urls.py мы должны написать следующее:
from django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r'^riddles/', include('riddles.urls')), url(r'^admin/', admin.site.urls), ]
Теперь, если мы запустим наше приложение http://127.0.0.1:8000/riddles/ , мы увидим «Hello, World!».
Установка базы данных
По умолчанию в Django используется SQLite, если она вас не устраивает, то вы можете ознакомиться с нашей статьей, в которой мы рассказываем, как безболезненно перейти с SQLite на MySQL.
Теперь откроем django_example/settings.py и взглянем на переменную INSTALLED_APPS , она хранит все приложения, которые активны в текущем проекте. По умолчанию она содержит:
- django.contrib.admin — админка, скоро мы ей воспользуемся.
- django.contrib.auth — система аутентификации.
- django.contrib.contenttypes — фреймворк для content types.
- django.contrib.sessions — сессионный фреймворк.
- django.contrib.messages — фреймворк для отправки сообщений.
- django.contrib.staticfiles — фреймворк для работы со статичными файлами.
Некоторые из этих приложений используют базы данных, но они еще не установлены, поэтому мы и видели «You have unapplied migrations; your app may not work properly until they are applied.». Поправить это можно следующим образом: python manage.py migrate . Вы должны увидеть следующее:
Operations to perform: Apply all migrations: admin, sessions, auth, contenttypes Running migrations: Rendering model states. DONE Applying contenttypes.0001_initial. OK Applying auth.0001_initial. OK Applying admin.0001_initial. OK Applying admin.0002_logentry_remove_auto_add. OK Applying contenttypes.0002_remove_content_type_name. OK Applying auth.0002_alter_permission_name_max_length. OK Applying auth.0003_alter_user_email_max_length. OK Applying auth.0004_alter_user_username_opts. OK Applying auth.0005_alter_user_last_login_null. OK Applying auth.0006_require_contenttypes_0002. OK Applying auth.0007_alter_validators_add_error_messages. OK Applying sessions.0001_initial. OK
Теперь создадим нашу модель. Для начала создадим Riddle и Option . В Riddle будет содержаться загадка, в Option — один из возможных ответов на нее.
from django.db import models class Riddle(models.Model): riddle_text = models.CharField(max_length=255) pub_date = models.DateTimeField('date published') class Option(models.Model): riddle = models.ForeignKey(Riddle, on_delete=models.CASCADE) text = models.CharField(max_length=255) correct = models.BooleanField(default=False)
Данная модель обеспечивает Django информацией, необходимой для создания схемы базы данных и database-access API для доступа к объектам. Теперь нам нужно привязать наше приложение к нашему проекту, делается это следующим образом:
INSTALLED_APPS = [ 'riddles.apps.RiddlesConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
После этого нужно сделать миграцию: python manage.py makemigrations riddles . Вы должны увидеть следующее:
Migrations for 'riddles': 0001_initial.py: - Create model Option - Create model Riddle - Add field riddle to option
Так мы говорим Django, что в моделях были сделаны некоторые изменения, и их нужно сохранить в качестве миграции.
Проверить, что сделает миграция, можно так: python manage.py sqlmigrate riddles 0001 (0001 — версия миграции, которую мы хотим проверить). На выходе мы получим:
BEGIN; -- -- Create model Option -- CREATE TABLE "riddles_option" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "text" varchar(255) NOT NULL, "correct" bool NOT NULL); -- -- Create model Riddle -- CREATE TABLE "riddles_riddle" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "riddle_text" varchar(255) NOT NULL, "pub_date" datetime NOT NULL); -- -- Add field riddle to option -- ALTER TABLE "riddles_option" RENAME TO "riddles_option__old"; CREATE TABLE "riddles_option" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "text" varchar(255) NOT NULL, "correct" bool NOT NULL, "riddle_id" integer NOT NULL REFERENCES "riddles_riddle" ("id")); INSERT INTO "riddles_option" ("riddle_id", "id", "text", "correct") SELECT NULL, "id", "text", "correct" FROM "riddles_option__old"; DROP TABLE "riddles_option__old"; CREATE INDEX "riddles_option_a7c97949" ON "riddles_option" ("riddle_id"); COMMIT;
Заметьте, что команда sqlmigrate нужна только для проверки, каждый раз ее запускать необязательно.
Теперь мы можем начать пользоваться панелью администратора. Но для этого нам нужен пользователь. Создать его можно следующим образом: python manage.py createsuperuser . После этого запускаем сервер, если он не запущен, и переходим на http://127.0.0.1:8000/admin/ . Вы увидите следующее:
Теперь дадим админу возможность изменять наши модели. Делается это так:
from django.contrib import admin from .models import Option, Riddle admin.site.register(Riddle) admin.site.register(Option)
Вот что получится в итоге:
Возьмите небольшую паузу и поиграйтесь с панелью администратора. Вы будете приятно удивлены тем, что умеет Джанго.
Главная страница
Что нам нужно для создания главной страницы?
- Templates: скелет нашей страницы.
- Views: функция на Python для отображения контента.
Начнем с шаблонов. Создадим папку templates внутри папки riddle , а в ней создадим index.html .
Теперь создадим макет для ответов:
>
>
Здесь мы используем csrf_token , он нужен для защиты от межсайтовой подделки запроса, каждая внутренняя форма должна его использовать. Теперь напишем виды для рендеринга наших шаблонов:
from django.http.response import HttpResponse from django.shortcuts import get_object_or_404, render from .models import Riddle, Option def index(request): return render(request, "index.html", ) def detail(request, riddle_id): return render(request, "answer.html", ) def answer(request, riddle_id): riddle = get_object_or_404(Riddle, pk=riddle_id) try: option = riddle.option_set.get(pk=request.POST['option']) except (KeyError, Option.DoesNotExist): return render(request, 'answer.html', ) else: if option.correct: return render(request, "index.html", ) else: return render(request, 'answer.html', )
Давайте пройдемся по каждой функции веб-приложения на Django отдельно:
- index: Index использует функцию render . На вход она получает HttpRequest, местонахождение шаблона и его содержимое, а возвращает HttpResponse с окончательным html.
- detail: Detail делает практически то же самое, но только функция get_object_or_404 возвращает HttpResponse404, если нужный объект не был найден.
- answer: Answer ищет предоставленную загадку (и возвращает 404, если она не найдена) и проверяет правильность ответа.
Теперь добавим наши функции в urls.py :
from django.conf.urls import url from . import views app_name = 'riddles' urlpatterns = [ url(r'^$', views.index, name='index'), url(r'^(?P[0-9]+)/$', views.detail, name='detail'), url(r'^(?P[0-9]+)/answer/$', views.answer, name='answer') ]
Стили
Для начала создадим директорию static , а в ней создадим файл main.css .
body < margin:40px auto; max-width:650px; line-height:1.6; font-size:18px; color:#444; padding:0 10px; >h1,h2,h3 < line-height:1.2; text-align: center; >a < color: blue; >form < margin: 0 auto; padding: 1em; border: 1px solid #CCC; border-radius: 1em; >form div + div < margin-top: 1em; >label < display: inline-block; text-align: center; width: 40%; >input < font: 1em sans-serif; -moz-box-sizing: border-box; box-sizing: border-box; border: 1px solid #999; width: 50%; >input:focus < border-color: #000; >p, div.button < text-align: center; >p.error-message
Немного изменим наши шаблоны: