Опубликован: 25.01.2016 | Уровень: для всех | Доступ: платный | ВУЗ: Российский Новый Университет
Лекция 5:

Введение в Хэштеги

< Лекция 4 || Лекция 5 || Лекция 6 >

Цель лекции: Рассмотреть понятие хэштега; создать модель хештега; рассмотреть понятие формы и основные поля формы; спроектировать формы публикации твита; создать страницу тегов.

Ключевые термины: Django, Python, форма, хештег, разработка, проект, , твит, приложение, модель, шаблон, class, версия

Теги – одна из самых известных особенностей приложение Веб 2.0. Тег – это ключевое слово, ассоциированное с кусочком информации, такой как статья, ссылка или изображение. Тегирование – процесс ассоциации тегов с содержимым. Обычно он делается автором или пользователями и разрешает пользовательскую каталогизацию контента.

Мы также используем теги в нашем проекте, назовем их хэштегами. Теги очень популярны в веб-приложениях, потому что они позволяют легко классифицировать, просматривать и делиться контентом. Если вы не знакомы с тегами, вы можете увидеть примеры, посетив такие социальные сайты, как Twitter, Facebook или Google Plus, где теги привязаны к каждому пользователю или обсуждению, чтобы помочь найди среди друзей самые обсуждаемые темы. С тех пор, как мы начали заниматься созданием сайта с микроблогами, теги помогут нам создать категории для обсуждений пользователей.

Для представления тегов в нашей системе, нам нужен механизм для отправки твитов в базу данных с хэштегом. Позже нам понадобится метод для просмотра твитов, относящихся к выбранному тегу.

Модель данных хэштега

Хэштеги нужно хранить в базе данных и ассоциировать их с твитами. Первый шаг для представления тегов – это создание модели данных для хэштегов. Объект хэштег содержит лишь один кусочек данных, строку, представляющую хэштег.

Вы можете обратиться к лекции 4, Построение приложение типа Twitter, мы там использовали разные ключи для связи твитов с пользователями, и назвали это отношением один-ко-многим. Конечно же, отношения между хэштегами и твитами не являются отношениями один-ко-многим, и твит может иметь много связанных с ним хэштегов. Это называется отношением многие-ко-многим, и это отношение представляется в моделях Django параметром models.ManyToManyField.

Вы должны хорошо помнить, что сейчас данные модели помещаются в файле mytweet|models.py. Вы должны открыть этот файл и добавить в него следующий класс HashTag:

class HashTag(models.Model):

"""
HashTag model

"""
name = models.CharField(max_length=64, unique=True
tweet = models.ManyToManyField(Tweet)
def _unicode (self):
     return self.name

Прямо загляденье, не правда ли? Мы просто определили модель данных для хэштега. Эта модель содержит имя тега и его твит в параметре models.ManyToManyField. Когда вы закончите набирать код, не забудьте выполнить следующую команду, чтобы создать таблицу для модели в базе данных:

$ python manage.py syncdb
Вывод: 

Creating tables ...
Creating table tweethashtagtweet 
Creating table tweethashtag 
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)

Сейчас мы посмотрим на расширенный запрос того, как Django создает и имплементирует все отношения и как создается для этого таблица, для этого можно использовать команду sql с именем таблицы в файле manage.py. Это покажет SQL-запросы, выполняющиеся для создания экземпляра объекта. Тем, кто знаком с SQL, знают, что отношения многие-ко многим создаются с помощью третьей таблицы, которая соединяется с таблицами отношений. Теперь посмотри, как Django определяет данный тип отношений. В терминале выполните следующую команду:

  $ python manage.py sql tweet

Вывод

BEGIN;
CREATE TABLE "tweettweet" (
"id" integer NOT NULL PRIMARY KEY,
"userid" integer NOT NULL REFERENCES "userprofileuser" ("id"), "text" varchar(160) NOT NULL,
"createddate" datetime NOT NULL,
"country" varchar(30) NOT NULL,
"isactive" bool NOT NULL
)
!
CREATE TABLE "tweethashtagtweet" (
"id" integer NOT NULL PRIMARY KEY,
"hashtagid" integer NOT NULL,
"tweetid" integer NOT NULL REFERENCES "tweettweet" ("id"),
UNIQUE ("hashtagid", "tweetid")
)
/
CREATE TABLE "tweethashtag" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(64) NOT NULL UNIQUE
)
i
COMMIT;

Результат может несколько отличаться в зависимости от вашего движка базы данных. Действительно Django автоматически создает дополнительную таблицу под названием tweet_hashtag_tweet для поддержки отношения многие-ко-многим.

Стоит отметить, что, когда мы определяем отношения многие-ко-многим в Django API модели, поле models.ManyToMany может быть размещено в любой из двух связанных моделей.Мы могли бы поместить это поле в модель твита вместо хэштега; Поскольку мы создали модель хэштега позже, мы оставим поле models.ManyToMany в ней.

Для целей тестирования, мы должны переместиться к панели администрирования и создать твит с хэштегами, так же как мы делали с созданием пользователя и твита. Но сперва мы должны зарегитсритовать твит и хэштеги для панели администрирования в файле admin.py.

Измененный файл admin.py будет выглядеть так:

from django.contrib import admin
from models import Tweet,Hashtag
#Register your models here,
admin.site.register(Tweet)
admin.site.register(HashTag)

Теперь мы можем переместиться к панели администрирования с помощью URL /admin.

Прежде чем мы создадим хэштег для твита, нам нужно создать твит для хэштега. Позе мы напишем программу, которая будет автоматически парсить твиты и связывать с ними экземпляр хэштега.

Обратитесь к демо-диаграмме твита, показанной нами в главе 4, Построение приложение типа Twitter, и создайте твит со следующим текстом:

Привет, #Django! вы великолепны.

Опубликуйте твит от имени того же пользователя, ratancs, мы его уже использовали, затем переместитесь к модели хэштега и создайте хэштег #Django, и свяжите его с созданным нами твитом. Это даст вам идею, как присоединить хэштег к твиту.

Давайте создадим правильную форму отправки твита, которая позволит выбирать пользователей для отправки твита в поле ввода. Это создаст все хэштеги, связанные с данным твитом и сохранит твит.

Давайте взглянем на страницу профиля пользователя, созданную нами. В центре страницы будет помещено поле ввода, уже связанное с пользователем; кроме этого, когда он создает твит и нажимает кнопку отправки, твит сохраняется с его ID.

Теперь, перейдите по следующей ссылке: http: //localhost: 8000/user/test/. Вы увидите так же твиты, созданные ранее.


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

Шаблон нашего файла profile.html будет выглядеть следующим образом:

{% extends "base.html" %}
{% block content %}
<div class="row clearfix">
<div class="col-md-12 column">
{% for tweet in tweets %}
<div class="well">
<span>{{ tweet.text }}</span>
</div>
{% endfor %}
</div>
</div>
{% endblock %}

Этот блок {%for . . .} используется для представления множества твитов, один под другим, каждый из которых заключен в тег div.

Сейчас мы создадим блок тега div прямо под блоком {%for . . .}, и добавим нашу форму отправки твитов.

Формы Django

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

Естественно, что Django поставляется с собственной библиотекой для обработки этих задач. Все, что вам нужно сделать, это импортировать библиотеку для ввода форм:

from django import forms 

Библиотека форм Django обрабатывает три общие задачи:

  • Генерация HTML-формы
  • Проверка ввода пользователя на стороне сервера
  • Отображение HTML-формы в случае ошибки ввода

Принцип работы этой библиотеки схож с принципом работы модели данных. Вы начинаете с определения класса, представляющего форму. Этот класс должен быть производным от базового класса forms.Form. Атрибуты в этом классе представляют поля формы. Пакет форм предоставляет множество типов полей.

Когда вы создаете объект из класса, который является производным от базового класса forms.Form., вы можете взаимодействовать с ним с использованием различных методов. Существуют методы для генерации HTML-кода, для доступа к входным данным и методы для проверки формы

Мы узнаем о библиотеке форм, создав форму публикации твита в следующем разделе.

Проектирование формы публикации твита

Начнем с создания нашей первой формы Django .Создайте новый файл в папке приложения tweets и назовите его forms.py. Затем откройте этот файл в редакторе кода и наберите следующий код:

from django import forms 
class TweetForm(forms.Form):
text = forms.CharField(widget=forms.Textarea(attrs={ ‘rows’: 1, 'cols': 85}), max_length=160)
country = forms.CharField(widget=forms.Hiddenlnput())

После проверки кода, вы заметите, что способ, которым мы определили этот класс, похож на способ, в котором мы определили классы модели. Класс TweetForm мы наследовали от класса forms.Form. Все формы нужно наследовать от своих классов.

Теперь мы определим поля, содержашиеся в этой форме:

text = forms.CharField(widget=forms.Textarea(attrs={ ‘rows’: 1, 'cols': 85}), max_length=160)

Форма содержит текстовое поле, которое будет иметь HTML-тег для текстовой области, дополнительные атрибуты для строк и столбцов, и максимальный размер для ввода, который является таким же, как максимальная длина твита.

country = forms.CharField(widget=forms.Hiddenlnput())

Пожалуйста, обратите внимание, что форма также содержит скрытое поле, названное country и типа char.

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

  • label: метка поля, когда происходит генерация HTML кода.
  • required: должен ли пользователь ввести значение или нет. Он устанавливается равным True по умолчанию. Чтобы изменить его, необходимо установить его равным False в конструкторе.
  • widget: этот параметр позволяет вам контролировать, как это поле отображается в формате HTML. Мы использовали его прямо сейчас, чтобы параметр пароля CharField стал полем ввода пароля.
  • help_text: описание данного поля будет отображаться при отрисовке формы.

Ниже приведен перечень часто используемых типов полей:

Тип поля Описание
CharField Возвращает строку.
IntegerField Возвращает целое число.
DateField Возвращает объект Python datetime.date
DateTimeField Возвращает объект Python datetime.datetime
EmailField Возвращает верный адрес электронной почты как строку
URLField Возвращает действительный URL-адрес в виде строки.

Вот неполный список доступных форме виджетов:

Тип виджета Описание
PasswordInput Текстовое поле пароля.
Hiddenlnput Скрытое поле ввода.
Textarea Текстовая область, которая разрешает многострочный ввод
Filelnput Поле загрузки файла.

Теперь мы должны изменить файл profile.html с учетом файла forms.py.

{% extends "base.html" %}
{% block content %}
<div class="row clearfix">
<div class="col-md-12 column">
<form method="post" action="post/">{% csrf_token %}
<div class="col-md-8 col-md-offset-2 fieldWrapper">
{{ form.text.errors }}
{{ form.text }}
</div>
{{ form.country.as_hidden }}
<div>
<input type="submit" value="post">
</div>
</form>
</div>
<h3> </h3>
<div class="col-md-12 column">
{% for tweet in tweets %}
<div class="well">
<span>{{ tweet.text }}</span>
</div>
{% endfor %}
</div>
</div>
{% endblock %}

Публикация твита достигается за счет простой формы, которая описывается с помощью <form method="post" action="post/">{% csrf_token %} . Методом, с помощью которого форма осуществляет публикацию, является "post", а относительным URL формы для публикации твита - ="post/">{% csrf_token %}.

Этот код создает CSRF токен, который фактически устраняет источник безопасности; Он защищает URL этого метода post от атак с другого сервера; Подробнее об этом мы объясним в следующем разделе этой главы.

Мы добавили тег div перед твитом <div>, и этот тег div содержит форму, которая сохраняет твит при нажатии на кнопку для отправки.

<div class="col-md-8 col-md-offset-2 fieldWrapper">
{{ form.text.errors }}
{{ form.text }}
</div>

Этот класс FieldWrapper в теге div используется библиотекой форм Django для отображения HTML-тега, который мы определили для текста в классе form, (являющемся Textarea), за которым следует случаи отрисовки формы при любой ошибке.

Отобразится форма, как показано на следующем скриншоте:

Теперь нам нужно сделать две вещи, чтобы заставить форму работать:

  1. Нам нужно определить метод, который будет брать запрос отправки этой формы и сохранять данные твита в нашу модель класса объекта твита.
  2. Необходимо определить шаблон URL, который будет публиковаться при отправке формы с содержимым твита.

Для привязки запроса мы должны создать новый класс, который будет принимать твит из формы. Мы назовем этот класс PostTweet. Этот класс добавляет в файл tweet/view.py зависимость импорта from tweet.forms import TweetForm.

class PostTweet(View):
    """Tweet Post form available on page /user/<username> URL"""
    def post(self, request, username):
        form = TweetForm(self.request.POST)
        if form.is_valid():
            user = User.objects.get(username=username)
            tweet = Tweet(text=form.cleaned_data['text'],
                                         user=user,
                                         country=form.cleaned_data['country'])
            tweet.save()
            words = form.cleaned_data['text'].split(" ")
            for word in words:
                if word[0] == "#":
                    HashTag, created = HashTag.objects.get_or_create(name=word[1:])
                    HashTag.tweet.add(tweet)
        return HttpResponseRedirect('/user/'+username)

Нам нужно только определить метод публикации, так как нам нужен этот класс только для принятия данных. Эта логика предельно ясна здесь; если форма верна, только тогда будут сохраняться данные. Всегда случается перенаправление. Код также выполняет одно важное задание; он отделяет все хэштеги от самого твита. Это выполняется тем же образом, похожим на то, как отделяются слова в твите, и, если слово начинается с # (хэш), создастся хэштег этого слова (подумайте здесь о регулярных выражениях). Для второй части, мы должны добавить вход в файл url.py, как показано ниже:

from django.conf.urls import patterns, include, url

from django.contrib import admin

from tweet.views import Index, Profile, PostTweet


admin.autodiscover()

urlpatterns = patterns('',
    url(r'^$', Index.as_view()),
    url(r'^user/(\w+)/$', Profile.as_view()),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^user/(\w+)/post/$', PostTweet.as_view())
)

Если вы присмотритесь к последней строке, она гласит:

url(r'^user/(\w+)/post/$', PostTweet.as_view())

Она означает, что все запросы формы /user/<username>/post будет отображаться PostTweet`ом.

Со всем этим. мы сделали простую форму Django, которая может осуществлять пользовательскую публикацию с его страницы в Twitter, как показано на следующем рисунке:


Когда твит опубликован, форма покажет все твиты, как показано на следующем изображении:

Создание страницы тегов

Теперь мы создадим страницу, похожую на страницу для просмотра хэштегов Twitter. Для этого, мы выстроим почти ту же самую архитектуру, что и для случая построения профиля пользователя. Давайте начнем с добавления URL записи для страницы хэштега. Откройте файл url.py и вставьте следующую строку (предпочтительно после записи страницы пользователя, чтобы сохранить организацию таблицы).

URL(r'^hashTag/(\w+) / $', HashTagCloud.as_view()),

Захваченная часть регулярного выражения такая же, как и на странице пользователя.

Мы только разрешим цифробуквенные символы в хэштеге.

Мы определим класс Hashtag в контроллере как показано далее

class HashTagCloud(View):
    """Hash Tag  page reachable from /hashTag/<hashtag> URL"""
    def get(self, request, hashtag):
        params = dict()
        hashtag = HashTag.objects.get(name=hashtag)
        params["tweets"] = hashtag.tweet
        return render(request, 'hashtag.html', params)

Шаблон HTML-страницы мы используем почти такой же, как и для профиля, кроме части формы, которую мы используем для опубликования твита.

Нам нужно создать файл hashtag.html со следующим кодом:

{% extends "base.html" %}
{% block content %}
<div class="row clearfix">
<div class="col-md-12 column">
{% for tweet in tweets.all %}
<div class="well">
<span>{{ tweet.text }}</span>
</div>
{% endfor %}
</div>
</div>
{% endblock %}

Это отобразит все твиты с хэштегом, переданным URL.

Контрольные вопросы

  1. Каково назначение CSRF токена?
  2. Что такое шаблон?
  3. Что такое хэштег
  4. Для чего используется компонент well?
  5. Что такое тегирование?

Упражнения

Упражнение 1.

Добавьте возможность публиковать время отправки твита с хэштегом

Упражнение 2.

Попробуйте добавить отправку эмотиконов вместе с текстом

Упражнение 3.

Добавьте поиск по тегам

Упражнение 4.

Создайте страницу, где будут отображаться архивные твиты по определенному хэштегу

Список тем курсовых работ

  • Разработка главной страницы мультимедиа-сайта
  • Прототипирование учебной социальной сети
  • Разработка формы как фактор создания интерфейса для пользователя
  • Разработка формы с помошью компонентов Twitter Bootstrap
  • Применение компонентов Twitter Bootstrap для разработки продающего приложения
  • Разработка прототипа интернет-магазина
  • Язык веб-разметки HTML
  • PEP-8
  • Роль виджетов в разработке на Django
  • Создание облака образовательных ресурсов

Краткие итоги

  • Научились работать с системой контроля версий
  • Изучили основные команды Git
  • Познакомились с редакторами тектов
  • Узнали об IDE Pycharn
  • Рассмотрели стиль кодирования на платформе Django
  • Изучили структуру проекта Django
  • Установили Twitter Bootstrap для быстрой разработки стилей проекта.
  • Настроили базу даных для первого проекта
  • Запустили сервер разработки
  • Познакомились с отличием проекта от приложения
< Лекция 4 || Лекция 5 || Лекция 6 >
Константин Боталов
Константин Боталов

Вроде легкие вопросы и ответы знаю правильные, но система считает иначе и правильные ответысчитает неправильными. Приходится выполнть по несколько раз. Это я не правильно делаю или тест так составлен?

Владимир Филипенко
Владимир Филипенко

Листинг показывает в 4-ой лекции, что установлен Django 1.8.4. Тут же далее в этой лекции указаны настройки, которые воспринимает Django 1.7 и младше.

Дмитрий Молокоедов
Дмитрий Молокоедов
Россия, Новосибирск, НГПУ, 2009
Акбар Ахвердов
Акбар Ахвердов
Россия, г. Москва