Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Python

Создание Ribbit на Django

by
Difficulty:IntermediateLength:LongLanguages:

Russian (Pусский) translation by Alex Grigorovich (you can also view the original English article)

После реализации нашего Twitter-клона, Ribbit, на чистом PHP и Rails, настало время сделать следующий шаг: Python! В этой статье, мы пересоздадим наш Ribbit используя Django. Итак, без лишних слов, начинаем!

Home Page

Step 0 - Bootstrapping

На время написания этой статьи, Django 1.4 поддерживал Python 2.5 по 2.7.3. Прежде всего, убедитесь что ваша версия Python соответствует требованиям, набрав python -v в терминале. Обратите внимание что предпочтительно использовать версию Python 2.7.3. На протяжении всей статьи, мы будем использовать pip как пакетный менеджер и virtualenv в качестве виртуального окружения. Что бы установить их, запустите терминал и выполните следующие команды от имени root

Устанавливать среду разработки Django, мы начнем с создания виртуального окружения (Virtual Environment). Выполните нижеследующие команды в вашем терминале (желательно внутри папки предназначенной для поекта)

Теперь наше виртуальное окружение установлено и активировано (ваша командная строка должна изменить вид, приглашение к вводу должно отображать имя вашего окружения), настало время установить все зависимости проекта.  Что бы управлять миграцией нашей базы данных мы будем использовать, независимо от Django, утилиту South. Для их установки мы будем использовать pip. Стоить заметить что начиная с текущего момента все, что мы будем делать, будет делаться внутри виртуального окружения (virtualenv). Как и раньше, перед работой, убедитесь что вы внутри него.

Теперь, когда все зависимости установлены, мы готовы перейти к созданию нового Django проекта.


Шаг 1 - Создание проекта и Ribbit App

Начнем же создание нового Django проекта и нашего приложения.  cd в выбранную вами директорию и выполните:

Далее, инициализируем наш git репозиторий и создадим  файл .gitignore внутри Ribbit проекта, которое мы только что создали. Сделаем это, выполнив:

Теперь приступим к редактированию ribbit/settings.py и конфигурированию нашего проекта. Для начала, мы определим некоторые константы. Добавим следующие строчки в начало файла:

Константа PROJECT_PATH будет хранить в себе путь к директории в которой лежит settings.py. Это позволит нам использовать относительные пути для определения будущих констант. LOGIN_URL, как и предполагает название константы,  обозначает, что корень нашего сайта будет URL-адресом для входа (обычный Login).

Двигаемся дальше! Давайте теперь сконфигурируем базу данных. Для первоначальной разработки, sqlite3 это просто идеальный выбор. Для этого, отредактируем константу DATABASES как показано ниже:

Django ищет статические файлы в директории указанной в константе STATIC_ROOT и направляет все запросы к файлам используя путь написанный в STATIC_URL. Сконфигурируем их, как показано ниже:

Обратите внимание на использование os.path.join(). Функция позволяет нам, с помощью константы PROJECT_PATH, определять относительный путь.

Далее нам нужно указать местоположение, в котором Django будет искать файлы шаблонов. Отредактируем константу TEMPLATE_DIRS что бы указать путь.

Наконец, давайте добавим South и ribbit_app в список INSTALLED_APPS.

Далее, давайте создадим директории, которые мы определили в настройках, и базу данных:  

Команда syncdb создаст требуемые таблицы и необходимый аккаунт супер пользователя. Т.к. мы используем South для миграций, мы сделаем начальную миграцию для нашего проекта используя конструкцию schemamigration <имя приложения> --initial и применим ее, командой python manage.py migrate ribbit_app

Давайте запустим наш тестовый сервер, что бы убедиться что все работает правильно.

И если все прошло гладко, то вас должна приветствовать  нижеследующая страница, как только вы войдете по адресу http://localhost:8000

Landing Page

В итоге дерево проекта должно выглядеть следующим образом:

Но перед тем как двигаться дальше, давайте закоммитим все изменения в наш репозиторий.


Шаг 2 - Базовый шаблон и статичные файлы

Перейдем на страничку уроков по интерфейсу, скачаем все файлы и положим их в папку ribbit_app/static. Нам надо только сделать некоторые изменения в файле style.less для этого урока. Давайте начнем с добавления стиля для вспомогательных сообщений.

Далее, обновим ширину элемента ввода и добавим новый класс для ошибок. Заметьте, что код, приведенный ниже, содержит только те строчки кода, что надо добавить или обновить. Остальной код останется без изменений.

Нам так же надо увеличить высоту #content.wrapper.panel.right.

Наконец, давайте добавим для картинок футера правый отступ.

Но перед тем как двигаться дальше, закоммитим наши изменения:

Далее, давайте создадим базовый шаблон, который будет унаследован всеми остальными нашими шаблонами. Django использует свой собственный шаблонный движок (по типу ERB или Jade). Определим шаблон в ribbit/templates/base.html со следующим содержимым:

В разметке, что наверху, {{ STATIC_URL }} выводит путь для статичных url, определенных в settings.py. Другая интересная возможность, это использование блоков. Все содержимое блоков наследуется потомками базового шаблона и не будет перезаписано, покуда блоки явно не будут переопределены в них. Это предоставляет нам некоторую гибкость при размещении навигации в шапке сайта и замене его на форму входа, если пользователь не авторизован. Мы так же используем блок с if условием, что бы проверить, есть ли любые переменные вспомогательных сообщений и есть ли что отображать.

Отлично! Время сделать еще один коммит:


Шаг 3 - Создание моделей

Одна из самых лучших черт в Django то, что он включает в себя множество уже готовых моделей и форм, которые могут быть переопределены для множества целей. Для нашего приложения мы будем использовать модель User и добавим несколько свойств к ней, при создании UserProfile. Кроме того, для того чтобы управлять пользователями Ribbit, мы создадим модель Ribbit. В Django есть поля для User имени пользователя, пароля, имени, фамилии и адреса электронной почты (с проверкой), а также другие поля. Я предлагаю вам взглянуть на API, чтобы изучить все доступные поля профайла. Теперь, добавьте следующий код для моделей в ribbit_app / models.py

Начнем с модели Ribbit. Атрибуты включают свойство CharField с максимальной длиной в 140 символов для хранения контента, модель ForeignKey для модели пользователя (таким образом, мы получаем отношение между двумя моделями) и DateTimeField, который автоматически сохраняет время, когда экземпляр модели сохранён.

Переходя к модели UserProfile, мы увидим поле OneToOne , которое определяет отношение «один к одному» с User моделью пользователя и полеManyToMany для реализации отношения next / follow_by. Параметр related_name позволяет нам использовать отношение в обратном направлении, используя имя по нашему выбору.  Мы также устанавливаем значение symmetrical на False, чтобы гарантировать, что если пользователь A следует B, то пользователь B автоматически не следует A.Мы также определили функцию для получения ссылки на изображение gravatar на основе URL-адреса пользователя и свойства  (если пользовательский файл существует для пользователя) или создать его, когда мы используем синтаксис <user_object>.profile. Это позволяет легко получить свойства объекта UserProfile.  Вот пример того, как вы можете использовать ORM, чтобы получить данные пользователей, на кого они подписаны и кто подписан на них.

Теперь, когда наши модели определены, давайте создадим файл миграции и применим их:

Прежде чем двигаться дальше, давайте применим изменения


Шаг 4 - Создание форм

Django позволяет нам создавать формы, чтобы мы могли легко проверять данные, принятые пользователем  Мы создадим пользовательскую форму для модели Ribbit и создадим форму, которая наследует UserCreationForm, представленную по умолчанию для управления регистрацией. Для управления аутентификацией мы расширим параметр AuthenticationForm, предоставленный по умолчанию в Django. Давайте создадим новый файл ribbit_app/forms.py и добавим импорт необходимых модулей.

Начнем с создания регистрационной формы. Мы назовем ее UserCreateForm, пример кода приведен ниже:

В приведенной выше примере мы явно указали некоторые из полей как обязательные, указав required = True. Кроме того, я добавил атрибут placeholder к различным виджетам, применимым формам. Класс с именем errorтакже добавляется в поля, содержащие ошибки. Это делается в функции is_valid(). Наконец, в классе Meta мы можем указать порядок, в котором мы хотим, чтобы формы поля отображались, и задали модель, с которой должна быть проверена форма.

Затем давайте напишем форму для аутентификации:

Как и в UserCreateForm, AuthenticateForm добавляет некоторые плэйсхолдер и классы ошибок.

Наконец, давайте закончим эту форму, и сохраним новую форму  Ribbit.

Опция exclude в вышеперечисленном классе Meta предотвращает визуализацию поля пользователя. Нам это не нужно, поскольку пользователь Ribbit будет обработа с помощью сеансов в Ribbit

Теперь применим  изменения


Шаг 5 – Регистрация и вход в систему

Django очень гибкая система, когда дело доходит до маршрутизации. Начнем с определения некоторых маршрутов в ribbit / urls.py

Далее, давайте использовать модели и формы, которые мы уже создали, и напишем соответствующие представления для каждого только что определенного маршрута. 

Начнем с добавления импорта в ribbit_app / views.py.

Для представления index мы сначала проверяем, зарегистрирован ли пользователь или нет, и соответственно визуализируем шаблон. Запросы ribributes_bibdies и ribbits_buddies объединены с символом оператора | в приведенном выше коде. Кроме того, мы проверяем, был ли экземпляр формы передан методу (в определении функции), и если мы не создаем новый. Это позволяет нам передавать экземпляры форм соответствующим шаблонам и отображать ошибки.

Давайте продолжим редактирование шаблона 'home.html', который будет использоваться для отображения индексной страницы для анонимных пользователей. В файле theribbit / templates / home.html добавьте следующий код.

В шаблоне мы наследуем базовый шаблон, определенный ранее, визуализируем и регистрируем формы, переопределяя блок входа. Приятная вещь в Django заключается в том, что она упрощает CSRF Protection!  Все, что вам нужно сделать, это добавитьcsrf_token в каждую форму, которую вы используете в шаблоне.

Перейдем к шаблону buddies.html, в котором будет отображаться страница друзей Ribbit. Отредактируйте ribbit / templates / buddies.html и добавьте следующий код:

В этом шаблоне мы предоставляем родительский шаблон i.e. base.html со значением имени пользователя, чтобы ссылка на навигацию для зарегистрированного пользователя отображалась правильно.  Мы также используем экземпляр RibbitForm, чтобы добавлять новых пользователей и показывать новых друзей наших пользователей

После того, как только шаблоны доработаны, давайте допишем код для входа / выхода пользователя.  Добавьте следующий код ribbit_app / views.py

Представления авторизации ожидают запроса через HTTP POST для входа (с тех пор как мы используем метод POST).  Он проверяет форму и вводит пользователя всистему, используя метод login(), который запускает сеанс, а затем перенаправляет нас на корневой URL-адрес.  Если проверка завершается неудачно, мы передаем экземпляр auth_form от пользователя к функции индекса и видим  ошибки, тогда как, если запрос не использует метод POST, пользователь перенаправляется на корневой URL-адрес.

Вид выхода довольно прост.  Он использует функцию logout() в Django, которая удаляет сеанс и регистрирует пользователя, а затем перенаправляется на корневой URL.

Теперь нам нужно написать представление, чтобы зарегистрировать пользователя и чтобы он смог войти.  Подключите следующий код к ribbit_app/views.py.

Подобно представлению входа в систему, окошко регистрации также ожидает запроса POST и перенаправляет на корневой URL-адрес, если проверка завершилась неудачей. Если форма регистрации действительна, пользователь сохраняется в базе данных, аутентифицируется, регистрируется и затем перенаправляется на домашнюю страницу. В противном случае мы вызываем функцию индекса и передаем в экземпляр user_form, представленный пользователем, чтобы перечислять ошибки.

Какой же у нас прогресс? Запустив сервер и протестировав просмотры, которые мы написали до сих.

Перейдем к серверу разработки и попробуем зарегистрировать нового пользователя. Если все идет хорошо, то вы увидите страницу друзей Ribbits. Мы можем выйти из системы и повторно проверить страницу созданного пользователя, для проверки всех функций  в режиме ожидании.

Buddies

Время применять изменения!


Шаг 6 –регистрация  новых пользователей Ribbits и список публичных аккаунтов Ribbits

В шаблоне buddies.html, который мы создали ранее, ribbit_form отправлялась через/submit.  Давайте отредактируем файлы ribbitbit / urls.py и добавим маршрут для формы и страницы,чтобы отобразить список аккаунтов. 

Давайте напишем представление, чтобы проверить и сохранить зарегистрированных пользователей. Откройте файл ribbit_app/views.py и добавьте следующий код:

Представление,которое использует декоратор @login_required, который выполняет функцию тольков том случае, если пользователь авторизирован; иначе, он будет перенаправлен на путь, указанный в константе LOGIN_URL в настройках. Если проверка формы прошла успешно, мы вручную устанавливает, что пользователю открыт сеанс , а затем сохраняем данные. После приема данных пользователь перенаправляется на путь, указанный в поле next_url, который является скрытым полем формы, вводимый нами в шаблон специально для этих целей.   Значение next_url передается в  представление,которое отображает форму Ribbit.

После перехода, давайте напишем представление, чтобы отобразить список последних 10 пользователей Ribbits.  Добавьте следующий код в файл ribbit_app/views.py.

При отображении публичной страницы,  мы запрашиваем в базе данных данные последних 10 пользователей, отфильтровывая данные  запросов последних 10 элементов.  Затем форма вместе с пользователями отображается в шаблоне.  Давайте создадим файл ribbit/templates/public.html для этого представления

В то время, пока обрабатывается  цикл с объектами пользователей, шаблон использует образец тега timesince, чтобы автоматически определять разницу между временем создания аккаунта и текущим временем и отображает это в стиле Twitter.

Убедитесь, что сервер разработки запущен, создайте нового пользователя и посмотрите на страницу Public Ribbits, чтобы все работало верно.

First Ribbit

Давайте сохраним изменения и продолжим:


Шаг 7-аккаунты пользователя и подписчиков

Наш Твиттер-клон, пользовательские профили и подписчики  идут рука об руку.  Давайте напишем маршруты для реализации этого функционала. Обновите файл ribbit/urls.py следующим образом:

Интересным типом маршрута является пример выше, который указывает  на профиль конкретного пользователя. <?P<username> фиксирует имя пользователя, полученного путем запроса GET, и значение \w {0,30}указывает на то, что максимальная длина для имени пользователя составляет 30 символов:

Затем мы продолжим писать представление для профайлов пользователей.  Добавьте следующий код в `ribbit_app/views.py '.

Это представление ,пожалуй, самое интересное из всех, что мы рассмотрели до сих пор.  Начнем с того, что только зарегистрированные пользователи могут просматривать профили пользователей. В маршрутах, которые мы определили в файле ribbit/ urls.py, мы использовали один из этих маршрутов, для получения имени пользователя. Этот полученный  параметр автоматически вызывается вместе с объектом из запроса о пользователях.  Мы имеем два варианта:

  • Имя пользователя передается в URL-адрес для отображения профиля конкретного пользователя
  • Имя пользователя отсутствует, что подразумевает, что пользователь хочет просмотреть все доступные профили

Начнем с проверки того, передалось ли имя пользователя и не пустое ли оно.  Затем мы попытаемся получить объект User для соответствующего имени пользователя.  Обратите внимание на использование блока catch try в коде выше.  Мы обрабатываем исключение Http404, используя возможности Django, чтобы перенаправить на страницу ошибки 404.  Затем нам нужно проверить, имеет ли запрашиваемый профиль друзей среди зарегистрированных пользователей.  Если это так, нам не нужно отображать следующую ссылку в профиле, поскольку отношения между пользователями уже установлены. В противном случае мы передаем параметр follow в представлении для отображения ссылки «Подписаться»

Переходя ко второму этапу, в случае, если в URL-адресе не указано имя пользователя, мы получаем список всех доступных пользователей и выполняем функцию annotate() чтобы добавить свойства ribbit_count ко всем объектам, которые содержат количество запросов на подписку  каждого пользователя Ribbits. Это позволяет нам использовать следующее значение  в строке <user_name>.ribbit_count Ribbit Count пользователя,чтобы получит количество подписчиков.

Получение данных о последних зарегистрированных пользователях немного сложно. Мы используем для этого встроенную функцию map()  в Python и применяем функцию get_latest() длявсех элементов  в запросе.  Функция get_latest() определена в коде выше и создает двустороннее отношение дляпользователей Ribbit. Например, реализация функции user.ribbit_set.all() вернет значение всех пользователей для конкретного пользователя. Мы упорядочиваем пользователей по их id в порядке убывания и получаем первый элемент.  Код заключен в блок catch try, чтобы получить данные, в случае, если у пользователя нет подписчиков.  Затем мы используем функцию zip() в Python для соединения каждого элемента обоих итераторов (пользователей и подписчиков), чтобы у нас была связь с пользовательским объектом и последней парой пользователей Затем мы передаем этот связанный объект вместе с формами в шаблон.  Давайте напишем наше последнее представление, которое будет принимать запрос от пользователя по подписку:

В приведенном выше представлении мы получаем значение параметра follow, переданного через запрос  POST.  Если идентификатор установлен, мы проверяем, существует ли пользователь и добавляем отношение, в противном случае мы получаем ошибку  bjectDoesNotExist и перенаправляем пользователя на страницу со списком всех доступных пользователей.

Мы завершили работу  с представлениями на данном этапе.  Давайте напишем оставшиеся два шаблона, необходимые для отображения профилей пользователей. Откройте текстовый редактор и отредактируйте файл ribbit/templates/profiles.html

Чтобы отобразить пользователя вместе со своим последним подписчиком, мы используем общую конструкцию в Python для перебора списка взаимосвязей for user, ribbit in obj j.  Внутри цикла мы отображаем  информацию о пользователе вместе с подписчиками.  Обратите внимание на использование обратной связи в {{user.profile.followed_by.count}}follow_by - это имя пользователя, которое мы установили при определении свойства ManyToMany  длямодели UserProfile.

Наконец, давайте напишем шаблон для отображения профиля конкретного пользователя. Запишите следующий код в файл ribbit / templates / user.html.

Как и в шаблоне buddies.html, мы передаем имя пользователя зарегистрированного шаблона в родительский , используя конструкцию {% with%}.  Затем мы отображаем профиль пользователя и показываем следующую ссылку только в том случае, если для переменной follow установлено значение True. После этого мы перечислим всех подписчиков для пользователя, прибавляя значения к переменной  ribbits.

Мы, наконец, сделали все представления и шаблоны.  Проверьте все ссылки и попробуйте подписаться на пользователей и наслаждайтесь только что созданным  вами клоном Twitter.

Давайте сохраним наши изменения: 


Шаг 8 – Размещение приложения на Heroku

Я предпочитаю разделять разработку на две ветви: разработка и публикация. С помощью git это можно сделать легко.

Запустите терминал и выполните следующие команды: Давайте обновим наш файл .gitignore и добавим к нему базу данных.  Этот файл должен содержать следующее:

Давайте установим некоторые расширения в наш virtualenv, которые необходимы для публикации на сервере.

Мы также создадим файл со всеми зависимостями проекта, чтобы они были применены Heroku.

Затем отредактируем файл ribbit / settings.py.  Настройки базы данных должны быть изменены соответственно:

В конце файла добавьте следующее, чтобы Heroku мог определить настройки базы данных.

Давайте создадим Procfile для запуска процесса на сервере Heroku. Добавьте следующий код в файл Procfile.

Кроме того, если ваше приложение не большое , вы можете пропустить настройки служб хранения, добавив маршрут для статических файлов в ribbit/urls.py

Мы всё настроили! Давайте закоммитим изменения:

Наконец, мы создадим приложение Heroku и переместим наши файлы на удаленный сервер:

После передачи файлов запустите syncdb и примените настройки миграции к базе данных.

Наконец, откройте  приложение с помощью:


Заключение

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

Экспериментируйте  вместе с моим приложением  в Heroku.  Если у вас есть какие-либо вопросы, я был бы рад ответить на них.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.