Django Framework для новичков - Урок 2

Здравствуйте!
Рады видеть Вас на втором уроке в серии уроков "Django для начинающих".
Сегодня мы создадим приложение "Новости", которое будет выводить новости на сайте в указанном месте.
Также, сделаем возможность добавлять новости из админки.

Итак, во первых, откройте папку apps и там создайте папку news, это и будет наше приложение.
В созданной папке news создайте пустой файл __init__.py.
Также, создайте файл models.py описывающий структуру приложения в Базе Данных, этот файл должен содержать следующий код:

# -*- coding: utf-8 -*- #Указываем кодировку, стандартно UTF-8

from django.db import models #Импортируем объект для работы с базой данных

class News(models.Model): #Создаем класс News, унаследованный от объекта Model
  title = models.CharField('Заголовок', max_length = 128) #Конструкция models.CharField() позволяет указать, что поле title в базе данных будет иметь длину 128, а в админке будет отображаться слово "Заголовок"
  slug_title = models.SlugField('Имя для ссылки', unique = True) #Дополнительный параметр unique требуется для того, что бы сделать поле уникальным
  pub_date = models.DateField('Дата публикации', blank = True, null = True) #blank и null указывает на то, что поле может быть пустым
  content = models.TextField('Содержание', blank = True, null = True) #Аналогично pub_date, может быть пустым
  show = models.BooleanField('Показывать', default = True) #Параметр default установленный в состояние True позволяет изначально отметить тип BooleanField галкой, то есть, изначально ровняется 1

  class Meta: #Создаем класс Meta
    ordering = ('-pub_date', ) #Указываем поле, по которому будут упорядочены результаты выборки, знак минуса в начале указывает на то, что результаты будут инвертированы (аналог DESC в PHP)
    verbose_name = 'Новость' #Название такого элемента (требуется для админки)
    verbose_name_plural = 'Новости' #Название нескольких таких элементов (требуется для админки)


Ок, тут все ясно? - Хорошо!
Поехали дальше.
Создаем файл привязки урлов приложения, называем его urls.py хотя можно назвать как хотите, но желательно стандартно - urls.py.
Помещаем в этот файл следующий код:

#-*- coding: utf-8 -*- #Указываем кодировку, стандартно UTF-8

from django.conf.urls.defaults import * #Импортируем все(*) из django.conf.urls.defaults

urlpatterns = patterns('news.views',#Указываем название приложения, у нас это news. После точки указываем название файла с функциями представления, у нас это будет views.py, значит указываем views
    url(r'view/(.+)/$', 'news_inside', name = 'news_inside'), #С помощью регулярных выражений говорим, что если урл заканчивается на view/ и какие-то символы, значит вызываем функцию news_inside
    url(r'.*$', 'news_list', name = 'news_list'), #С помощью регулярных выражений говорим, что если урл заканчивается на любой набор символов, или вообще является пустым, значит вызываем функцию news_list
)

Все понятно? - Отлично!
Кстати, обратите внимание на порядок построения урлов :)
Если их поставить по другому, работать не будет.
Поехали дальше.
В принципе осталось 2 файла.

Теперь, создаем главный файл, файл с функциями представления views.py.
В него помещаем следующий код:

# -*- coding: utf-8 -*- #Указываем кодировку, стандартно UTF-8

from django.template import RequestContext #Запрашиваем Request параметры
from django.shortcuts import render_to_response, get_object_or_404 #Подключаем функции рендера запроса, а также, get_object_or_404 - вернуть объект или 404

from models import News #Из списка моделей запрашиваем модель News, то есть, ту, что мы описывали в файле models.py

def news_inside(request, RSlug_Title): #Объявляем функцию news_inside, принимающую 2 параметра, а именно, request и RSlug_Title, где RSlug_Title это то, что мы выделяли круглыми скобками в урл привязках приложения
  return render_to_response('news/news_inside.html', #Указываем шаблон функции, то есть, в корне в папке templates есть(или будет) папка news, в которой есть файл news_inside.html который и является шаблоном функции
  {
    'new': get_object_or_404(News, slug_title = RSlug_Title, show = True), #Объявляем шаблонную переменную new, присваиваем ей значение отображаемой новости, или 404
																		 #В параметрах указываем модель, откуда производить выборку - News, а также, указываем, что поле slug_title должно ровняться request параметру RSlug_Title и поле show должно быть в состоянии true
  }, context_instance = RequestContext(request), )

def news_list(request):
  return render_to_response('news/news_list.html',
  {
    'news': News.objects.filter(show = True), #Запрашиваем список всех объектов из модели News, фильтруем по признаку show = True
  }, context_instance = RequestContext(request), )


И последний файл, требующийся для того, что бы мы могли создавать/редактировать/удалять новости в админке, это файл admin.py.
Создаем его и вносим вот такой код:

# -*- coding: utf-8 -*- #Указываем кодировку, стандартно UTF-8

from django.contrib import admin #Импортируем объект для работы с админкой
from models import News #Импортируем модель News из списка моделей

class NewsAdmin(admin.ModelAdmin): #Объявляем класс NewsAdmin, унаследованный у объекта ModelAdmin
  list_display = ('title', 'slug_title', 'pub_date', 'show', ) #Указываем, какие поля отображать в списке новостей в админке
  list_filter  = ('pub_date', 'show', ) #Указываем, по каким полям фильтровать список новостей
  search_fields = ('title', 'content', ) #Указываем, в каких полях производить поиск в админке
  prepopulated_fields = {'slug_title': ('title', ) } #Означает то, что поле slug_title при заполнении будет автоматически заполняться при наборе поля title, только символы будут конвертироваться в латиницу

admin.site.register(News, NewsAdmin) #Регистрируем новый объект в админке

В принципе приложение готово, осталось только зарегистрировать его и создать 2 шаблона для вывода новостей.
Идем в папку templates, которая находится в корне и создаем в этой папке другую папку под названием news.
В созданной папке создаем 2 файла, а именно, news_list.html и news_inside.html.

В файл news_list.html помещаем следующий код:

{%extends "base.html"%}

{%block title%}Django - Новости{%endblock%}

{%block content%}

<div style="background-color: #2C2C2C; color: #309BC9; font-size: 25px; font-family: Tahoma sans-serif; padding: 5px; padding-left: 10px;" >Список новостей</div>
<div style="background-color: #EEEEEE; padding: 5px;">

<ul style="list-style: none;">
{%for yet_another_one_news_item in news%}

<li><a style="color: #444444; font-size: 17px; font-family: Tahoma sans-serif;" href="/news/view/{{yet_another_one_news_item.slug_title}}/">{{yet_another_one_news_item.title|safe}}</a></li>

{%endfor%}
</ul>

</div>

{%endblock%}

В файл news_inside.html помещаем вот такой код:

{%extends "base.html"%}
{%block title%}{{new.title}}{%endblock%}
{%block content%}
<div style="background-color: #2C2C2C; color: #309BC9; font-size: 25px; font-family: Tahoma sans-serif; padding: 5px; padding-left: 10px;" >
<a style="color: #FFFFFF; font-size: 23px; font-family: Tahoma sans-serif; float: right;" href="/news/">Назад</a>
{{new.title|safe}}
</div>
<div style="background-color: #EEEEEE; padding: 5px;">{{new.content|safe}}</div>
{%endblock%}

Ну вот, теперь осталось зарегистрировать приложение и добавить основной урл в спискок корневых урл привязок.
Открываем файл settings.py в корне сайта и ищем там массив INSTALLED_APPS, в конец этого массива добавляем название нашего приложения.
Должно получится примерно так:

INSTALLED_APPS = (
    'grappelli',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
    'flatpages',
    'south',
    'treemenus',
    'sorl.thumbnail',
    'pagination',
    'tinymce',
    'pytils',
    #'announcements',
    'news',
)

Далее, открываем файл urls.py в корне сайта и добавляем корневую URL привязку к созданному нами приложению.
В качестве предпоследнего элемента массива указываем привязку вида:

(r'^news/', include('news.urls')),

В итоге файл urls.py будет выглядить примерно так:

from django.conf.urls.defaults import *

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    (r'^admin/', include(admin.site.urls)),
    (r'^tinymce/', include('tinymce.urls')),
    (r'^grappelli/', include('grappelli.urls')),
    (r'^news/', include('news.urls')),
    (r'', include('flatpages.urls')),
)

Внимание!
Важно поставить новую привязку именно до последнего элемента flatpages, поскольку в нашем случае приложение flatpages перехватывает все
урлы вида /(.*) то есть, и наше приложение оно тоже попытается перехватить.
Именно поэтому, ставим созданное нами приложение news до приложения flatpages и т.п., что бы все работало, как надо.

На этом все!
Приложение создано, однако, при попытке посетить админку или т.п. страницы связанные с новым приложением, появится ошибка базы данных.
Мы объявили новую модель БД для приложения, но никаких изменений в данный момент в БД нет, то есть, наше приложение есть в коде, но его нет в БД.
Можно конечно вручную с помощью phpMyAdmin добавить нужную таблицу с нужными полями, но это во первых не надежно, во вторых долго.
Поэтому, используем менеджер Django для синхронизации модели приложения с базой данных.

Запускаем WinSCP, подключаемся к серверу, после чего запускаем Putty и вбиваем следующие команды по очереди:
cd public_html
python manage.py schemamigration news --initial
python manage.py migrate news

Эти команды позволяет автоматически синхронизировать модель приложения с базой данных.
Внимание, первую команду cd public_html, ее мы используем для того, что бы перейти в корневой каталог.

На этом все, поздравляем!
Вы создали свое первое приложение на Django!
Теперь заходите в админку и добавляйте новости.
По адресу LOGIN.tmweb.ru/news/ будет доступен список новостей.
Кликните на одну из новостей и Вы увидите ее полную версию :)

Если у Вас что-то не получается или появляются странные ошибки, пишите об этом в комментарии.
Не забывайте указывать ошибку, но не указывайте всю ошибку, указывайте только ее заголовок.

В следующей статье мы создадим новое приложение "Категории", а также, дополним приложение "Новости", что бы новости можно было размещать в категориях.

Удачи!

 Уроки по Django   4673     0  20  12.12.2013
 Нравится?
 Расскажи друзьям
 Комментарии