Публичный сайт, который отображает пользователям голосования и позволяет им голосовать.
Интерфейс администратора, который позволяет вам добавлять, изменять и удалять голосования.
Where to get help:
Если у вас возникли проблемы при выполнении этого урока, оставьте сообщение на django-users или попросите помощи в чате #django on irc.freenode.net.
django-admin.py startproject mysite
Script name may differ in distribution packages
Если вы установили Django используя пакетный менеджер дистрибутива Linux (например, apt-get или yum), django-admin.py может называться django-admin и вам следует опустить .py из команд.
Примечание
Вы не должны использовать в качестве названия проекта названия компонентов Python или Django. Это означает, что проект не может называться django (что конфликтует с Django) или test (конфликтует со стандартным пакетом Python).
Where should this code live?
Если вы раньше использовали PHP, то наверное привыкли располагать код проекта в корневой каталог сайта на Web-сервере (например, /var/www). C Django вы не должны этого делать. Это плохая идея добавлять код проекта в корень Web-сервера, так как есть риск, что он будет доступен для просмотра. Не делайте этого в целях безопасности.
Расположите код в каталоге вне сервера, например /home/mycode.
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
Doesn’t match what you see?
Структура проекта по-умолчанию была недавно изменена. Если вы видите “простую” структуру (без внутреннего каталога mysite/), возможно вы используете версию Django которая не соответствует этому учебнику. Вам следует читать старую версию учебника или обновить Django.
Внешний каталог mysite/ – просто контейнер для вашего проекта. Его название никак не используется Django и вы можете назвать его как угодно.
manage.py: скрипт, который позволяет вам взаимодействовать с проектом Django. Подробности про manage.py читайте в разделе django-admin.py and manage.py.
Внутренний каталог mysite/ это пакет Python вашего проекта. Его название – это название пакета Python, которое вы будете использовать для импорта чего-либо из проекта (например, import mysite.settings).
mysite/__init__.py: пустой файл, который указывает Python, что текущий каталог является пакетом Python. (Читайте о пакетах в официальной документации Python если вы новичок в Python.)
mysite/settings.py: Настройки/конфигурация проекта. Раздел Django settings расскажет вам все о настройках проекта.
mysite/urls.py: Конфигурация URL-ов для вашего проекта Django. Это “содержимое” всех Django-сайтов. Вы можете прочитать о конфигурации URL-ов в разделе Менеджер URL-ов.
mysite/wsgi.py: Точки входа для WSGI-совместимый веб-серверов. Подробности читайте в разделе How to deploy with WSGI.
Validating models...
0 errors found.
Django version 1.4, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Changing the port
По-умолчанию, команда runserver запускает сервер для разработки на локальном IP используя порт 8000.
Если вы хотите изменить порт, укажите его через аргумент. Например, эта команда запускает сервер используя порт 8080:
python manage.py runserver 8080
Если вы хотите изменить IP, передайте его вместо со значением порта. Что бы прослушивать все публичные IP (полезно, если вы хотите показать свою работу на других компьютерах), используйте:
python manage.py runserver 0.0.0.0:8000
Смотрите полное описание команды runserver.
ENGINE – Доступные значения: 'django.db.backends.postgresql_psycopg2', 'django.db.backends.mysql', 'django.db.backends.sqlite3' или 'django.db.backends.oracle'. Так же доступны другие бэкэнды.
NAME – Название базы данных. Если вы используете SQLite, база данных будет файлом на вашем компьютере; в таком случае NAME должна содержать полный путь, включая название этого файла. Если файл не существует, он будет автоматически создан при первой синхронизации базы данных (смотрите ниже).
При определении пути, всегда используйте прямой слэш, даже в Windows (например, C:/homes/user/mysite/sqlite3.db).
USER – имя пользователя базы данных (не используется для SQLite).
PASSWORD – пароль к базе данных (не используется для SQLite).
HOST – хост на котором находится база данных. Оставьте пустым, если база данных находится на одном сервере с проектом (не используется для SQLite).
Примечание
Если вы используете PostgreSQL или MySQL, убедитесь что вы создали базу данных. Мы можете сделать это выполнив запрос “CREATE DATABASE database_name;” в консоли базы данных.
Если вы используете SQLite, вам ничего не нужно создавать самостоятельно - файл базы данных будет создан при необходимости.
django.contrib.auth – Система аутентификации.
django.contrib.contenttypes – “content types” фреймверк.
django.contrib.sessions – Фреймверк сессии.
django.contrib.sites – Фреймверк для использования нескольких сайтов с одной инсталяцией Django.
django.contrib.messages – Фреймверк сообщений.
django.contrib.staticfiles – Фреймверк для работы со статическими файлами.
python manage.py syncdb
For the minimalists
Как мы уже сказали, приложения по-умолчанию полезны в большинстве проектов, но не во всех. Если вы не нуждаетесь в некоторых или во всех, закоментируйте или удалите соответствующие строки в INSTALLED_APPS перед запуском syncdb. Команда syncdb создает таблицы только для приложений в INSTALLED_APPS.
Projects vs. apps
Какая разница между приложением и проектом? Приложение – это Web-приложение, которое предоставляет определенный функционал – например, Web-блог, хранилище каких-то записей или простое приложение для голосования. Проект – это совокупность приложений и конфигураций сайта. Проект может состоять из нескольких приложений. Приложение может использоваться несколькими проектами.
python manage.py startapp polls
polls/
__init__.py
models.py
tests.py
views.py
Philosophy
Модель - это основной источник данных. Он содержит набор полей и поведение данных, которые вы храните. Django следует принципу DRY. Смысл в том, что бы определять модели в одном месте.
from django.db import models
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice = models.CharField(max_length=200)
votes = models.IntegerField()
Создать структуру базы данных (CREATE TABLE) для приложения.
Создать Python API для доступа к данным объектов Poll и Choice.
Philosophy
Приложения Django “подключаемые”: вы можете использовать приложение в нескольких проектах и вы можете распространять приложение, так как они не связаны с конкретным проектом Django.
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
# 'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
'polls',
)
python manage.py sql polls
BEGIN;
CREATE TABLE "polls_poll" (
"id" serial NOT NULL PRIMARY KEY,
"question" varchar(200) NOT NULL,
"pub_date" timestamp with time zone NOT NULL
);
CREATE TABLE "polls_choice" (
"id" serial NOT NULL PRIMARY KEY,
"poll_id" integer NOT NULL REFERENCES "polls_poll" ("id") DEFERRABLE INITIALLY DEFERRED,
"choice" varchar(200) NOT NULL,
"votes" integer NOT NULL
);
COMMIT;
Полученные запросы зависят от базы данных, которую вы используете.
Названия таблиц созданы автоматически из названия приложения(polls) и названия модели в нижнем регистре – poll и choice. (Вы можете переопределить это.)
Первичные ключи (ID) добавлены автоматически. (Вы можете переопределить и это.)
Django добавляет "_id" к названию внешнего ключа. (Да, вы можете переопределить и это.)
Внешний ключа определяется явно через REFERENCES.
Учитываются особенности базы данных, которую вы используете. Специфические типы данных такие как auto_increment (MySQL), serial (PostgreSQL), или integer primary key (SQLite) будут использоваться автоматически. То же касается и экранирование называний, что позволяет использовать в названии кавычки – например, использование одинарных или двойных кавычек. Автор этого урока использует PostgreSQL, так что примеры используют синтаксис PostgreSQL.
Команда sql не выполняет SQL запросы в базе данных - она просто выводит их на экран, чтобы вы могли увидеть какой SQL создает Django. Если вы хотите, можете скопировать и выполнить этот SQL в консоли вашей базы данных. Однако, Django предоставляет более простой способ выполнять SQL в базе данных.
python manage.py validate – Проверяет на ошибки структуру ваших моделей.
python manage.py sqlcustom polls – Выводит дополнительные SQL запросы (такие как изменения в таблице или дополнительные правила) определенные для приложения.
python manage.py sqlclear polls – Выводит необходимые DROP TABLE запросы для этого приложения, учитывая таблицы, которые уже существуют в базе данных (если такие есть).
python manage.py sqlindexes polls – Выводит CREATE INDEX запросы для приложения.
python manage.py sqlall polls – Выводит комбинацию SQL запросов команд sql, sqlcustom, из sqlindexes.
python manage.py syncdb
python manage.py shell
Bypassing manage.py
Если вы не хотите использовать manage.py, не проблема. Просто установите переменную окружения DJANGO_SETTINGS_MODULE в mysite.settings и выполните python из каталога, в котором находится файл manage.py (или убедить, что каталог находится в путях Python, и import mysite работает).
Полную информацию обо всем этом смотрите в разделе о django-admin.py.
>>> from polls.models import Poll, Choice # Import the model classes we just wrote.
# No polls are in the system yet.
>>> Poll.objects.all()
[]
# Create a new Poll.
# Support for time zones is enabled in the default settings file, so
# Django expects a datetime with tzinfo for pub_date. Use timezone.now()
# instead of datetime.datetime.now() and it will do the right thing.
>>> from django.utils import timezone
>>> p = Poll(question="What's new?", pub_date=timezone.now())
# Save the object into the database. You have to call save() explicitly.
>>> p.save()
# Now it has an ID. Note that this might say "1L" instead of "1", depending
# on which database you're using. That's no biggie; it just means your
# database backend prefers to return integers as Python long integer
# objects.
>>> p.id
1
# Access database columns via Python attributes.
>>> p.question
"What's new?"
>>> p.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
# Change values by changing the attributes, then calling save().
>>> p.question = "What's up?"
>>> p.save()
# objects.all() displays all the polls in the database.
>>> Poll.objects.all()
[<Poll: Poll object>]
class Poll(models.Model):
# ...
def __unicode__(self):
return self.question
class Choice(models.Model):
# ...
def __unicode__(self):
return self.choice
Why __unicode__() and not __str__()?
Если у вас есть опыт работы с Python, вы наверное уже привыкли добавлять метод __str__() в ваши классы, не __unicode__(). Мы используем метод __unicode__() потому что модели Django работают с Unicode по-умолчанию. Все данные из базы данных конвертируются в Unicode при получении.
Модели Django содержат метод __str__(), который вызывает метод __unicode__() и конвертирует результат в UTF-8 байтовую строку. Это означает, что unicode(p) вернет строку Unicode, и str(p) вернет обычную строку, символы которой закодированы в UTF-8.
Если все это звучит бессмысленно для вас, просто не забывайте добавлять метод __unicode__() в ваши модели. Если повезет, все должно работать без проблем.
import datetime
from django.utils import timezone
# ...
class Poll(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
>>> from polls.models import Poll, Choice
# Make sure our __unicode__() addition worked.
>>> Poll.objects.all()
[<Poll: What's up?>]
# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Poll.objects.filter(id=1)
[<Poll: What's up?>]
>>> Poll.objects.filter(question__startswith='What')
[<Poll: What's up?>]
# Get the poll whose year is 2012.
>>> Poll.objects.get(pub_date__year=2012)
<Poll: What's up?>
>>> Poll.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Poll matching query does not exist.
# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Poll.objects.get(id=1).
>>> Poll.objects.get(pk=1)
<Poll: What's up?>
# Make sure our custom method worked.
>>> p = Poll.objects.get(pk=1)
>>> p.was_published_recently()
True
# Give the Poll a couple of Choices. The create call constructs a new
# choice object, does the INSERT statement, adds the choice to the set
# of available choices and returns the new Choice object. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a poll's choices) which can be accessed via the API.
>>> p = Poll.objects.get(pk=1)
# Display any choices from the related object set -- none so far.
>>> p.choice_set.all()
[]
# Create three choices.
>>> p.choice_set.create(choice='Not much', votes=0)
<Choice: Not much>
>>> p.choice_set.create(choice='The sky', votes=0)
<Choice: The sky>
>>> c = p.choice_set.create(choice='Just hacking again', votes=0)
# Choice objects have API access to their related Poll objects.
>>> c.poll
<Poll: What's up?>
# And vice versa: Poll objects get access to Choice objects.
>>> p.choice_set.all()
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
>>> p.choice_set.count()
3
# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want; there's no limit.
# Find all Choices for any poll whose pub_date is in 2012.
>>> Choice.objects.filter(poll__pub_date__year=2012)
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
# Let's delete one of the choices. Use delete() for that.
>>> c = p.choice_set.filter(choice__startswith='Just hacking')
>>> c.delete()
Mar 30, 2016