
Захотелось мне поведать как использовать связь ManyToMany, начал я значит писать пост, но так как я хотел его детализировать то он слишком разросся... И я решил сначала написать пост о том, как создавать первый проект и приложение на Django, чтобы потом ссылаться сюда.
— начинал я этот пост писать еще в том году, да все руки не доходили его закончить, спасибо vasa_c за терпение
Устанавливаем Django
Заходим на страницу , скачиваем (или выше). Далее, как и в инструкции:
wget -O Django-1.1.1.tar.gz http://www.djangoproject.com/download/1.1.1/tarball/
tar -xzvf Django-1.1.1.tar.gz
cd Django-1.1.1
sudo python setup.py install
Все, джанго установлен!
Так как мы будем работать с MySQL, то вам надо установить библиотеку py-mysqldb, представляющая собой интерфейс к MySQL.
Для Ubuntu:
Для FreeBSD
make install clean
А для Windows можно скачать .
Создаем наш первый проект
Допустим, что имя проекта у нас будет «myproject»:
django-admin.py startproject myproject
Теперь создайте себе новую БД «myproject»:
И отредактируйте «/www/myproject/settings.py», заменив только соответствующие части:
...
# Настройки БД
DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
DATABASE_NAME = 'myproject' # Or path to database file if using sqlite3.
DATABASE_USER = 'username' # Not used with sqlite3.
DATABASE_PASSWORD = 'password' # Not used with sqlite3.
DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
...
# Путь до каталога, где лежат наши медиа файлы (css, js, images)
MEDIA_ROOT = '/www/myproject/static/'
...
# URL медиа файлов (css, js, images)
MEDIA_URL = '/'
...
# URL медиа файлов админки (css, js, images, etc)
ADMIN_MEDIA_PREFIX = '/admin-media/'
...
# Путь до каталога с шаблонами
TEMPLATE_DIRS = (
"/www/myproject/blog/templates",
)
...
# Установленные приложения в нашем проекте
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
'myproject.blog',
)
# в конец добавлено две строки, первая подключает джанговскую админку,
# а второе наше приложение, которое мы ниже опишем
Для чего я ставлю в начале строки «#~*~ coding: utf-8 ~*~» читайте .
Создаем наше первое приложение
После того, как вы создали проект, надо создать приложение, если у вас проект состоит из одного приложения — можете его назвать «main».
Создаем приложение «blog»:
python manage.py startapp blog
Файл модели
Теперь перейдем к разработке модели нашего приложения, отредактируем «/www/myproject/blog/models.py».
У нас будет пока одна сущность, это Посты в Блоге:
# импортируем класс модели
from django.db import models
# и админки
from django.contrib import admin
'''
Blog posts
'''
class Post(models.Model):
# название поста
title = models.CharField(max_length=100)
# содержимое поста
text = models.TextField()
# функция необходима для того, чтобы при выводе объекта Post
# как строки выводился вместо этого его title
def __unicode__(self):
return self.title;
'''
Класс для админки, тут будут дополнительные атрибуты необходимые для админки
'''
class PostAdmin(admin.ModelAdmin):
# в таблице списка постов выводить только колонку title, если вы добавите еще одно имя поля, то и оно выведется
list_display = ('title',)
# связываем эту модель с моделью PostAdmin
admin.site.register(Post, PostAdmin)
Вы можете все что связано с админкой вынести в admins.py и импортировать его, чтобы избавится от лишнего кода
После создания файла моделей, вам необходимо запустить синхронизацию с БД, для того чтобы создались структуры данных:
python manage.py syncdb
Для более детального изучения команд manage.py введите:
python manage.py helpЕсли вас интересует конкретная комманда, например syncdb, то:
python manage.py help syncdbВы так же можете создавать свои команды, но об этом поговорим не в этот раз.
syncdb создаст таблицы в вашей БД, а также при первой инициализации попросит создать рутовую учетную запись для вашего проекта в django (это будет админский аккаунт):
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_user_permissions
Creating table auth_user_groups
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table django_admin_log
Creating table blog_post
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'root'):
E-mail address: mail@example.com
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
Installing index for admin.LogEntry model
Когда вы создадите новый класс модели вам будет необходимо вновь запустить syncdb.
Если вы внесли изменения в уже синхронизированное приложение, а именно в его модель, то syncdb НЕ внесет их в вашу БД, для этого используйте sqlall и другие sql* комманды:
Или попробуйте расширение для Django (для этого необходимо его установить в вашу систему и добавить в INSTALLED_APPS — «django_evolution»).
Файл урлов
Для навигации по вашему проекту вам нужен роутер (URL диспетчер).
Отредактируем «/www/myproject/urls.py»:
# импортируем админку
from django.contrib import admin
# Makes the patterns() function available
from django.conf.urls.defaults import *
# импортируем наши вьюхи (см. ниже описание файла вьюх)
from myproject.blog.views import main_page, get_post
# Above we used admin.autodiscover() to automatically load the INSTALLED_APPS admin.py modules
admin.autodiscover()
urlpatterns = patterns('',
# Если ничего не введено, то отдаем управление mainpage вьюхе
(r'^$', main_page),
# Если передан id поста, то отдаем управление get_post вьюхе
(r'^post/([0-9]{1,5})', get_post),
# Если введен /admin/, то идем в админку
(r'^admin/', include(admin.site.urls)),
)
Вы конечно можете отредактировать локальный для приложения «blog» — urls.py («/www/myproject/blog/urls.py»), но тогда вам надо будет импортировать «/www/myproject/blog/urls.py» в корневом «urls.py». Либо вы можете его определить в settings.py (ROOT_URLCONF).
Файл вьюхи
Ту роль, которую играет «Controller» в MVC, в Django играет роль View. Почему это так читайте .
Отредактируем «/www/myproject/blog/views.py»:
# функция генерирующая 404 страницу
from django.http import Http404
# функция отрисовки страницы, принимающая путь до шаблона и данные помещенные в шаблон
from django.shortcuts import render_to_response
# наша модель
from myproject.blog.models import Post
def main_page (request):
# Получаем список постов
posts = Post.objects.all()
# отрисовываем
return render_to_response('list.html', {"posts": posts})
def get_post (request, post_id):
try:
# выбираем конкретный пост, pk - primary key
post = Post.objects.get(pk=post_id)
except Post.DoesNotExist:
# если такого поста нет, то генерируем 404
raise Http404
# отрисовываем
return render_to_response('single.html', {"title": post.title, "text": post.text})
Вывод в шаблоне
В Django очень мощный и гибкий шаблонизатор, у него даже есть аналог на PHP — Twig, что говорит о его удобстве (был бы неудобным — не копировали бы), хотя Twig по слухам сильно хуже.
Однако, есть более крутой шаблонизатор для Django — , с более высокой производительностью и более гибкими возможностями. Описывать Jinja я не буду, ведь не это цель сего поста, поэтому делюсь только ссылочками:
С более полными возможностями Django Template вы можете познакомится на .
В Django Template поддерживается наследование, поэтому мы напишем общий шаблон и будем его использовать base.html:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>{% block title %}Default{% endblock %} / MyProject</title>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
Шаблон вывода списка постов list.html:
{% block title %}List!{% endblock %}
{% block content %}
<ul style="list-style-type:none">
{% for post in posts %}
<li style="padding-left:10px;{% if forloop.counter0|divisibleby:"4" %}background-color:#E1F3C9{% endif %}">
<a href="/post/{{ post.id }}/">{{ post.title }}</a>
<p>{{ post.text }}</p>
</li>
{% endfor %}
</ul>
</div>
{% endblock %}
Шаблон вывода одной записи single.html:
{% block title %}{{ title }}{% endblock %}
{% block content %}
<h1>{{ title }}</h1>
<div>
{{ text }}
</div>
{% endblock %}
Nginx
Теперь настроим Nginx для того, чтобы запуская «manage.py runserver» нам не прописывать порт в URL и чтобы использовать нормальное имя хоста, хотя вы может вполне без это обойтись.
Но я очень рекомендую использовать Nginx.
listen 80;
server_name myproject.loc;
location ^~ /admin-media {
alias /usr/local/lib/python2.6/dist-packages/django/contrib/admin/media;
}
location /static/ {
root /www/myproject/static/;
}
location ~* \.(jpg|jpeg|gif|png|ico|css|zip|js|swf)$ {
root /www/myproject/static/;
expires 7d;
}
location / {
proxy_pass http://127.0.0.1:8001/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Добавить в «/etc/hosts» ваш хост:
И перезагрузить Nginx:
nginx -s reload
# или для ubuntu/debian через скрипт инициализации
service nginx restart
/etc/init.d/nginx restart
# или для freebsd
/usr/local/etc/rc.d/nginx restart
Запускаем веб-сервер проекта на 8001 порту, так как мы туда будем проксировать из Nginx:
python manage.py runserver 8001
Теперь зайдите в админку (), введите вашу «root» учетку, которую создавали при syncdb.
Вы можете скачать архив с исходниками проекта тут
Вот мы и познакомились с первым приложение на Django, как я и обещал в начале этого поста следующая статья будет о ManyToMany, где мы подключим к нашему «Блогу» возможность создавать и выводить теги, а также расскажу более полно о возможностях моделях и ORM, View и о URL диспетере.
P.S. Пост дописывал в торопях, если найдете любые ошибки — обязательно отпишитесь в комментарии, спасибо!

Спасибо!
Ты охуен!
Расставь sudo где надо, не все такие хардкорные.
Разве не правильнее будет поставить django из пакетной системы,
как и все остальное?
aptitude install python-django (в squeeze сейчас 1.1.1-5)
cd /usr/ports/www/py-django ; make ; make install
P.S. textarea у коммента какая-то странная, в FF при размере окна
800×480 на моем eeepc 701 длинные строки не переносятся
vasa_c, спасибо, ты тоже)
ну я не только писал для «убунты», поэтому судо — лишнее. И вообще она не относится к делу, кто как работает. Вообще возможно кто-то под www создает проект и ему точно незачем sudo :)
bappoy,
Вот именно что «1.1.1-5», а сейчас есть 1.2, в этом вся проблема пакетов... С портами все конечно лучше, но всеравно не то. Лично я вообще использую версию из транка
Ага, тоже заметил, хотя у меня на нетбуке 1366×768 (заметил из-за увеличения шрифта в броузере), сенк, поправлю
эта, а если в роутере ни один шаблон не совпал и я хочу передать управление другому роутеру (Database)?
думаю несложно догадаться, кто это пишет)
Сам недавно сел за официальный туториал по Django. В документации к версии 1.2 есть небольшие отличия от того что Вы описываете, а так все классно. Отдельное спасибо за конфиг Nginx-а =)
Добавь в конце
...
(r'^.*', include(myproject.myurls)),
)
А в myurls.py будет твой роутер
xoma, вам спасибо за лестный фидбек )
bappoy, поправил верстку формы комментирования в блоге, стало лучше?
да, стало намного лучше, большое спасибо! а еще кнопку «отправить» не видно, она появляется только при нажатии на tab, при этом форма съезжает влево.y
Кнопку поправил, сейчас лучше? :)
Ага, теперь все на месте, еще раз спасибо!
Тебе спасибо!
Привет! Классный туториал, спасибо за труды!)
Есть пара вопросов:
1) если меняются настройки в проекте или в других файлах (urls.py, views.py), нужно ли перезагружать апач? кажется без перезагрузки ничего не меняется
2) сделал все по твоей инструкции, админка (/admin/) почему-то не открывается пишет 404 ошибку и {'path': u'admin/'} при этом морда сайта грузится и выводит List.html
Alexander, откажитесь от использования apache, используйте для разработки runserver, а для продакшена — nginx+tornado
Хорошая статья, но есть вопросы:
1) Не получается подключить css-файлы.
2) Можете описать настройку apache для работы с django?
1. Что именно вы делаете, по порядку опишите
2. adw0rd.ru/2009/modpython/ и секцию посмотрите «Настройка Apache» на adw0rd.ru/2009/trac-freebsd/
1. В settings.py задал MEDIA_ROOT, включающий путь к папке media; ADMIN_MEDIA_PREFIX='/media/'; MEDIA_URL = '/'.
Далее, в шаблоне подключаю css-файл. Испробовал много разных вариантов, но ни один не срабатывает...
2. Спасибо! Очень хорошо описано.
1. Вам надо назначить alias для MEDIA_URL и ссылать на каталог MEDIA_ROOT, если у вас apache. Если у вас nginx, то посмотрите как у меня сделано
На сколько я понимаю, назначать alias надо в настройках apache? Я еще не настраивал сервер, а работаю со встроенным джанговским. Полагал, что для работы с ним настраивать ничего не надо... Или я ошибаюсь
?
Я отдаю статику через nginx и не встречался с вопросом как отдать статику через runserver. Думаю это возможно, но это совсем не его задача, так что лучше воспользуйтесь nginx или другим вебсервером предназначенный для этих целей
Попробую настроить. Спасибо.