Разработка архитектуры веб-сервиса закрытой социальной сети с использованием фреймворка Django

Особенности функционирования закрытых частных социальных сетей, членство в которых доступно только для избранных. Сведение риска потери конфиденциальной информации к минимуму посредством ограничения доступа к социальным сетям. Структура web-приложения.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 09.09.2015
Размер файла 1,9 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Федеральное агентство по образованию Российской Федерации

Государственное образовательное учреждение

высшего профессионального образования

"КУБАНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ"

Кафедра математического моделирования

КУРСОВАЯ РАБОТА

Разработка архитектуры веб-сервиса закрытой социальной сети с использованием фреймворка Django

Работу выполнила студентка 4-го курса

Михно В.Д.

Краснодар - 2013

Научный руководитель,

Доцент, к. ф-м. н.

С.Е. Рубцов

Содержание

  • Введение
  • 1. Анализ закрытых социальных сетей
  • 2. Структура Web-приложения
  • 2.1 База данных и административная часть
  • 2.2 Логическая часть приложения и отображение данных на страницах
  • Заключение
  • Список использованных источников
  • Приложение А
  • Приложение В

Введение

В настоящее время количество социальных сетей в Интернете и численность их участников растет с невероятной быстротой. Социальные сети уже сегодня посещает более чем две трети онлайн-аудитории во всем мире, и это четвертая по популярности онлайн-категория после поисковых порталов, информационных порталов и программного обеспечения, которая опережает даже электронную почту (по данным компании Nielsen Online, исследующей онлайн поведение в 9 странах). По данным той же компании, использование онлайн-сообществ сегодня растет вдвое более быстрыми темпами, чем любой из четырех других секторов сети Интернета и в три раза быстрее, чем пользование Интернетом в целом. Социальные сети (social networks) привлекают людей, преследующих различные цели: поддержание контакта со старыми знакомыми и поиск новых, в т. ч. обустройство личной жизни; поиск работы, продвижение своего бизнеса, профессиональное общение; обмен информацией и медиаконтентом с другими пользователями. В России социальные сети развиваются с недавнего времени, но, не смотря на свою молодость многие сети, приобрели уже огромную популярность.

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

Интеграция обычных сайтов с внешними социальными сетями уже довольно активно вошла в нашу жизнь. Многие миллионы сайтов тесно интегрировались с самыми популярными сетями, и почти все новые проекты сегодня создаются с интеграцией по умолчанию. Это может быть в виде ссылок на официальные сообщества поклонников сайта в социальных сетях, могут быть кнопки отправки информации в социальные сети, кнопки "мне нравится", интеграция интернет-магазинов для продажи товаров, специальные приложения для работы с сетями, инструменты комментирования через социальные сети и многое другое. Следующим шагом будет создание специализированных платформ для интеграции, которые позволят создавать "социальную" экосистему внутри сайтов, и пользователи, будучи залогиненными в Facebook или VK, смогут получать все то же, что и в самой социальной сети, только при этом будучи на стороннем сайте. Тот же процесс можно будет сделать и в обратном направлении: пользователи смогут, не выходя из социальной сети, получать нужную им информацию со сторонних сайтов. В свою очередь, внешние сайты с удовольствием принимают инструменты интеграции, потому что это дополнительный приток посетителей из сетей, а значит, и дополнительная прибыль. Так социальные сети концентрируют в руках власть, можно сказать "подсаживают сайты на интеграцию".

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

Некоторые работодатели запрещают пользоваться социальными сетями - не только ради экономии, но и чтобы воспрепятствовать утечке информации.

закрытая социальная сеть фреймворк

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

1. Анализ закрытых социальных сетей

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

ASmallWorld Одна из самых первых эксклюзивных европейских социальных сетей, принимающая только "людей из мира высокого искусства, которые определяются по трем параметрам". Вы должны быть приглашены кем-то из существующих членов данной сети, но даже в этом случае нет никакой гарантии, что вас примут. Руководит сетью 25?летний швейцарец Патрик Лиотард-Войт (Patrick Liotard-Vogt).

Рисунок 1 - Социальная сеть ASmallWorld

Decayenne

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

Создатели сети описывают ее как "оазис вдохновения и развлечений" для "космополитичного, независимого, значимого, толерантного, либерального нонконформиста".

Рисунок 2 - Decayenne

Ecrika.ru

Evrika.ru - закрытая социальная сеть для российских врачей. Принадлежит медиа - группе "MedInform Healthcare Communications". Все страницы сайта, кроме главной, не индексируются поисковиками и доступны только зарегистрированным пользователям. Для получения доступа нужно быть действующим врачом, способным подтвердить свои профессиональные знания и факт работы в медицинском учреждении.

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

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

Социальная сеть для адвокатов.

Недавно созданная закрытая социальная сеть адвокатов набирает обороты. Адвокатское сообщество России включает примерно 65000 человек.65000 человек профессиональных юристов, объединенных Федеральным Законом "Об адвокатской деятельности и адвокатуре в Российской Федерации", кодексом профессиональной этики адвоката. Каждый адвокат, пришедший в сеть, чувствует родную среду, плечо коллеги, единство интересов и профессионализм.

Структура закрытой социальной сети адвокатов синхронна существующей в России структуре адвокатского сообщества. Адвокаты объединены в группы адвокатских Палат регионов.

В сети нет ников, каждый знает с кем общается, ведь адвокат - открытая профессия.

В сети нет места бюрократии, рекламе и платным услугам. Сеть создана адвокатами и для адвокатов.

Закрытость проекта обусловлена не тайнами и интригами, а особым языком и наречием. Темы и вопросы, обсуждаемые адвокатами, связаны именно с профессией. Информационная площадка, объединяющая всех адвокатов России от Республики Адыгея до республики Саха, дает возможность профессионального общения и установления горизонтальных связей.

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

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

Постановка задачи

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

Первое что необходимо сделать, это подключить модуль регистрации django-registration и систему идентификации пользователей, предоставляющую работу с пользователями, группами пользователей, правами и сессиями пользователей, работающими через cookies. Эта система представляется приложением django. contrib. auth., обеспечивающее доступ к модели User, которая будет отвечать за базу данных, в которую будут заноситься все регистрируемые пользователи. Без регистрации доступ к страницам будет ограничен.

Весь функционал сайта разбит на 4 приложения. Первое должно будет осуществлять отображение и редактирование личной информации. Второе отображение новостей для всех пользователей. Третье поиск друзей по логину, фамилии, имени или отчеству, а также возможность отправки сообщения, добавления, удаления, отклонения и принятия в друзья другого пользователя. И последнее четвертое, будет отвечать за обмен сообщениями между пользователями.

Каждое приложение будет состоять из двух частей:

· Общедоступная часть, которая дает людям возможность управлять своим профилем.

· Административная часть, которая позволит администратору редактировать базу данных сайта.

Эти две части будут реализовываться следуя шаблону Модель-Представление-Контроллер (Model-View-Controller, MVC). Примем, что MVC определяет способ разработки программного обеспечения при котором код для определения и доступа к данным (модель, файл models. py) отделен от логики приложения (управление, файл views. py), которая в свою очередь отделена от интерфейса пользователя (представление, файл html).

2. Структура Web-приложения

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

Основой проекта будут manage. py, __init__. py, settings. py, urls. py, wsgi. py.

· manage. py скрипт, который позволяет вам взаимодействовать с проектом Django.

· __init__. py пустой файл, который указывает Python, что текущий каталог является пакетом Python.

· settings. py настройки/конфигурация проекта.

· urls. py конфигурация URL-ов для вашего проекта Django. Это "содержимое” всех Django-сайтов.

· wsgi. py точки входа для WSGI-совместимый веб-серверов.

Содержимое этих файлов представлено в ПРИЛОЖЕНИИ А.

Скачав и подключив модуль django-registration, и установив приложение django. contrib. auth., можем переходить к той части проекта, которая будет отвечать за функционал нашего сайта.

2.1 База данных и административная часть

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

Класс Profile будет содержать поля типа AutoOneToOneField, ImageField, TextField, CharField и ManyToManyField.

AutoOneToOneField - связь один-к-одному, в отличие от связи многие-ко-многим возвращает один объект. Указывает на модель User и осуществляет доступ к объекту данной модели.

Поле ImageField - предназначено для загрузки изображения.

Рисунок 3 - Поле User типа AutoOneToOneField и поле Иконка типа ImageField

Поле TextField - большое текстовое поле. Интерфейс администратора отображает поле как <textarea>.

CharField - Строковое поле для хранения коротких или длинных строк. Интерфейс администратора отображает поле как <input type="text">.

ManyToManyField - Связь многое-ко-многому. Принимает позиционный аргумент: класс связанной модели. В нашем случае мы используем это поле для определения друзей для каждого пользователя. Использование в качестве позиционного аргумента 'self', позволяет нам создать рекурсивную связь, т.е. объект со связью многие-ко-многим на себя. Это значит, что мы будем помещать в это поле ссылки на объекты из этой же модели.

В этом же файле models. py будут описаны две модели Message и Chat, которые позволяют обмениваться сообщениями между друзьями.

Модель Message содержит два поля AutoOneToOneField, DateTimeField, определяющее поле для ввода даты, CharFiels, TextField и BooleanField (Рис.4). Последнее нам необходимо для определения, что сообщение отправлено и принято (т.е. прочитано). Это поле будет заполняться галочкой, когда получатель зайдет на страницу СООБЩЕНИЯ и просмотрит чат, в котором появилось новое сообщение.

Рисунок 4 - Административная часть. Модель Message.

Что касается модели Chat, так она предназначена для распределения всех объектов модели Message на чаты. Модель содержит два поля многое-к-одному - ForeignKey, ссылающиеся на модель User, для определения участников чата, и поле ManyToManyField для хранения объектов модели Message, пара получатель и отправитель которых соответствует двум полям ForeignKey модели Chat (Рис.5).

Рисунок 5 - Модель Chats. Объект модели содержащий 3 поля: первые два для определения участников чата, а второе для хранения объектов модели Message.

Теперь перейдем к файлу models. py приложения отвечающего за новостную ленту.

Две модели Blog и Comment. Модель Blog ссылается, с помощью поля ManyToManyField, на модель Comment. Модель Comment содержит два поля типа TextField для распределения текста новости.

Если текст оказывается слишком большим, то пользователь большую часть отправляет в нижнее поле, и на странице появляется новость только с тем, что было в первом поле и ссылка "читать полностью >>".

При нажатии на эту ссылку появляется полный текст с возможностью комментировать его.

Так как эти две модели похожи на Message и Chat, поэтому не будем останавливаться на них. Они представлены в ПРИЛОЖЕНИИ В.

2.2 Логическая часть приложения и отображение данных на страницах

Функционал главной страницы представлен двумя функциями my_profile и user_settings.

По названиям можно догадаться, какая функция за что отвечает. Первая my_profile, будет отображать главную страницу пользователя (Рис. 6):

Рисунок 6 - Отображение данных модели Profile.

Как мы видим, внизу всех данных есть ссылка на редактирование своих данных. Все поля для ввода каких-либо данных реализуются с помощью модельных форм, которые аналогичны моделям, или просто форм. И те и другие реализуются с помощью вспомогательных классов, которые описаны в ПРИЛОЖЕНИИ В.

Рисунок 7 - Редактирование данных модели Profile.

Весь код данных страниц представлен в ПРИЛОЖЕНИИ B.

Приложение, отвечающее за поиск друзей, позволяет находить по фамилии, имени, отчеству и логину пользователя (Рис. 8).

Рисунок 8 - Поисковая форма

При нажатии на ссылку "Добавить в друзья", искомый пользователь заносится в модель Profile в поле friends (ManyToManyField) и у, добавляемого в друзья, пользователя в поле friend_requests модели Profile отмечается тот пользователь, который только что прошел по ссылке "Добавить в друзья" (Рис. 9).

Рисунок 9 - Административная часть. Поле ManyToManyField - friend_requests. В этом поле выделяется синим пользователь, который хочет добавиться в друзья.

На странице у добавленного друга автоматически появится оповещение о пользователе, который его добавил в друзья и две ссылки "Принять друга" и "Отклонить друга".

После этих операций у вас появляется список пользователей, которых вы добавили себе в друзья, с возможностью удалить друга или написать ему сообщение (Рис. 10).

Рисунок 10 - Страница с моими друзьями и возможностью поиска новых.

Теперь рассмотрим функционал обмена сообщениями. При прохождении в меню по ссылки СООБЩЕНИЯ мы попадаем на страницу где показаны лишь чаты и их последние объекты из поля ManyToManyField - messages (Рис. 11).

Рисунок 11 - Страница сообщений. Отображение содержимого модели Chat.

Как мы видим на Рис. 11 отобразилось одно поле, которое содержит логин собеседника, дату последнего сообщения и само сообщение. Если кто то присылает сообщение, то возле ссылки СООБЩЕНИЯ появляется число, указывающее сколько новых сообщений (Рис. 12). Django позволяет самим создавать теги, описывая их действия на языке Python. Реализация этого шаблонного тега представлена в ПРИЛОЖЕНИИ В.

Рисунок 12 - Отображение появления нового сообщения.

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

<p>СООБЩЕНИЯ{% if user. id|message_count %} ({{ user. id|message_count}}) {% endif %}</p>

Далее заходим в СООБЩЕНИЯ и нажимаем на чат. Внизу чата видим что новое сообщение отображается синим (Рис.13). При обновлении страницы синий фон заменяется белым, как и у всех остальных сообщений.

Рисунок 13 - Отображение всех сообщений в данном чате.

При отправке нового сообщения, оно также будет становиться синим и у самого отправителя, до тех пор, пока получатель его не прочтет (Рис. 14).

Рисунок 14 - Отправка сообщения собеседнику.

Ну и теперь переходим к последней части сайта - НОВОСТИ.

Страница содержит сортировку по датам, отображение всех новостей и возможность добавлять свои новости (Рис. 15).

Рисунок 15 - Страница НОВОСТИ

Поля "Архивы" генерируются автоматически при добавлении новой новости с другим месяце и годом. При прохождении по одной из таких ссылок на страницу отображаются только те новости, у которых дата публикации обладает таким же месяцем и годом. При переходе по ссылке "Читать полностью >>", мы переходим на страницу, которая отображает всю новость, и внизу появляется поле для ввода комментария (Рис.16). Система отображения новых комментариев такая же как и у сообщений. Пока отправитель новости не прочтет новый комментарий, фон будет оставаться синим.

Рисунок 16 - Просмотр всей новости и комментариев к ней.

При нажатии на ссылку "Отправить сообщение", появляется форма для написания новости (Рис.17). Как мы уже говорили в разделе 3.1, если текст слишком велик, то пользователь может разбить его на две части, так что бы на главной странице новостей была видна только первая часть новости.

Рисунок 17 - Форма для заполнения новости.

Заключение

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

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

Планируется дальнейшее развитие проекта - добавление фото - и видео - галереи, а также, с помощью API Яндекс. translate и API Яндекс. Карты, добавить перевод всего сайта и размещения на изображении местности различных графических объектов.

Следовательно, приложение не утратит актуальности и будет в дальнейшем гораздо полезнее.

Список использованных источников

1. Форсье Дж., Биссекс П., Чан У. Django. Разработка веб-приложений на Python. - Пер. с англ. - СПб.: Символ-Плюс, 2010. - 456 с., ил.

2. Лутц М. Программирование на Python, том ? - ? ?, 4-е издание. - Пер. с англ. - СПб.: Символ-Плюс, 2011. - 992с., ил.

3. Django - http://ru. wikipedia.org/wiki/Django.

4. Object-Relational Mapping - http://ru. wikipedia.org/wiki/ORM.

5. Django 1.5 documentation - https: // docs. djangoproject.com/en/1.5/.

Приложение А

Файл manage. py

#! /usr/bin/env python

from django. core. management import execute_manager

import imp

try:

imp. find_module ('settings') # Assumed to be in the same directory.

except ImportError:

import sys

sys. stderr. write ("Error: Can't find the file 'settings. py' in the directory containing %r. It appears you've customized things. \nYou'll have to run django-admin. py, passing it your settings module. \n" % __file__)

sys. exit (1)

import settings

if __name__ == "__main__":

execute_manager (settings)

Файл setting. py

# - * - coding: utf-8 - *-

# Django settings for SA project.

DEBUG = True

TEMPLATE_DEBUG = DEBUG

ADMINS = (

# ('Your Name', 'your_email@example.com'),

)

MANAGERS = ADMINS

"""

пароль и логин если я опять как обычно забуду

для админки

viktoria

12345

"""

DATABASES = {

'default': {

'ENGINE': 'django. db. backends. mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.

'NAME': 'kfnexus_kurs', # Or path to database file if using sqlite3.

'USER': '045320128_kurs', # Not used with sqlite3.

'PASSWORD': '12345', # Not used with sqlite3.

'HOST': '127.0.0.1', # Set to empty string for localhost. Not used with sqlite3.

'PORT': '3306', # Set to empty string for default. Not used with sqlite3.

}

}

"""

№ настройки для локалхсота

EMAIL_HOST = '192.168.137.12'

EMAIL_PORT = '1025'

"""

EMAIL_USE_TLS = True

EMAIL_HOST = 'smtp. jino.ru'

EMAIL_HOST_USER = 'test@epsilon-design.ru'

EMAIL_HOST_PASSWORD = 'test'

EMAIL_PORT = 587

TIME_ZONE = 'Europe/Moscow'

LANGUAGE_CODE = 'ru-ru'

SITE_ID = 1

USE_I18N = True

USE_L10N = True

ROOT_URLCONF = 'SA. urls'

SITE_ROOT = '/home/users1/k/kfnexus/django/kurs2/SA/'

MEDIA_ROOT = '/home/users1/k/kfnexus/domains/kurs2. epsilon-design.ru/' + 'media/'

MEDIA_URL = '/media/'

STATIC_ROOT = '/home/users1/k/kfnexus/domains/kurs2. epsilon-design.ru/' + 'static/'

STATIC_URL = '/static/'

ADMIN_MEDIA_PREFIX = '/admin/'

STATICFILES_DIRS = ()

STATICFILES_FINDERS = (

'django. contrib. staticfiles. finders. FileSystemFinder',

'django. contrib. staticfiles. finders. AppDirectoriesFinder',

)

SECRET_KEY = '%jh+z=pal8) *6=m3@=-e ( (p66nhy2ej (yc! ^g4n8qgo*z) _$d-'

TEMPLATE_CONTEXT_PROCESSORS = (

"django. contrib. auth. context_processors. auth",

"django. core. context_processors. request",

"django. core. context_processors. i18n",

'django. contrib. messages. context_processors. messages',

'django. core. context_processors. debug',

'django. core. context_processors. media',

'django. core. context_processors. static',

)

MIDDLEWARE_CLASSES = (

'django. middleware. csrf. CsrfViewMiddleware',

'django. middleware.common.commonMiddleware',

'django. contrib. sessions. middleware. SessionMiddleware',

'django. contrib. auth. middleware. AuthenticationMiddleware',

'django. contrib. messages. middleware. MessageMiddleware',

'django. middleware. doc. XViewMiddleware',

'django. middleware. locale. LocaleMiddleware',

)

TEMPLATE_DIRS = (

SITE_ROOT + 'teamplates',

)

INSTALLED_APPS = (

'SA. filebrowser',

'django. contrib. auth',

'django. contrib. contenttypes',

'django. contrib. sessions',

'django. contrib. sites',

'django. contrib. messages',

'django. contrib. staticfiles',

'django. contrib. admin',

'django. contrib.comments',

'registration',

# курсовая:

'SA. user_profile',

'SA. rialto',

'SA. blog',

'SA. kurs',

'SA. friends'

)

LOGGING = {

'version': 1,'disable_existing_loggers': False,

'handlers': {

'mail_admins': {

'level': 'ERROR',

'class': 'django. utils. log. AdminEmailHandler'

}

},

'loggers': {

'django. request': {

'handlers': ['mail_admins'],

'level': 'ERROR',

'propagate': True,

},

}

}

gettext_noop = lambda s: s

PAGE_LANGUAGES = (

('ru', gettext_noop ('Russian')),

('en-us', gettext_noop ('US English')),

)

languages = list (PAGE_LANGUAGES)

LANGUAGES = languages

CACHE_BACKEND = "locmem: // /? max_entries=5000"

PAGE_USE_SITE_ID = True

SITE_ID = 1

'plugins': "autolink,lists,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions, iespell, inlinepopups, insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template",

'theme': "advanced",

'theme_advanced_buttons1': "save,newdocument,|,bold, italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect",

'theme_advanced_buttons2': "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent, indent,blockquote,|,undo,redo,|,link,unlink,anchor, image,cleanup,help,code,|, insertdate, inserttime,preview,|,forecolor,backcolor",

'theme_advanced_buttons3': "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions, iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen",

'theme_advanced_buttons4': "insertlayer,moveforward,movebackward,absolute,|,styleprops,spellchecker,|,cite,abbr,acronym,del, ins,attribs,|,visualchars,nonbreaking,template,blockquote,pagebreak,|, insertfile, insertimage",

'theme_advanced_toolbar_location': "top",

'theme_advanced_toolbar_align': "left",

'theme_advanced_statusbar_location': "bottom",

'theme_advanced_resizing': True,

'custom_undo_redo_levels': 10,"relative_urls": False,

}

TINYMCE_FILEBROWSER = True

TINYMCE_SPELLCHECKER = True

TINYMCE_COMPRESSOR = False

# заставляем базу данных этого хостинга (sweb.ru) работать с правильной кодировкой

"""

from django. db import connection, transaction

cursor = connection. cursor ()

cursor. execute ("SET NAMES 'utf8' COLLATE 'utf8_general_ci'")

transaction.commit_unless_managed ()

"""

#-- - Настройки для джанго рестрации - ---

ACCOUNT_ACTIVATION_DAYS = 7 # One-week activation window; you may, of course, use a different value.

AUTH_PROFILE_MODULE = 'user_profile. Message'

AUTH_PROFILE_MODULE = 'user_profile. Profile'

Файл url. py

# - * - coding: utf-8 - *-

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

from django. conf import settings

from django. contrib import admin

from django. contrib. staticfiles. urls import staticfiles_urlpatterns

from SA. user_profile. models import Profile

from SA. user_profile. signals import *

from SA. user_profile. forms import RegistrationFormProfile

from SA. user_profile. signals import *

admin. autodiscover ()

urlpatterns = patterns ('',

url (r'^accounts/register/$', 'registration. views. register', {'backend': 'registration. backends. default. DefaultBackend', 'form_class': RegistrationFormProfile,},name='registration_register'),

(r'^accounts/', include ('registration. backends. default. urls')),

# новый файлбраузер без гарппели

url (r'^admin/', include (admin. site. urls)),

url (r'^media/ (? P<path>. *) $', 'django. views. static. serve', {'document_root': settings. MEDIA_ROOT, }),

url (r'^static/ (? P<path>. *) $', 'django. views. static. serve', {'document_root': settings. STATIC_ROOT, }),

(r'^person/user_settings/$', 'SA. kurs. views. user_settings'),

(r'^$', 'SA. kurs. views. my_profile'),

(r'^friends/$', 'SA. friends. views. search_person'),

(r'^friends/add/ (? P<id> [^/] +) /$', 'SA. friends. views. add_person'),

(r'^friends/del/ (? P<id> [^/] +) /$', 'SA. friends. views. del_person'),

(r'^friends/accept/ (? P<objid> [^/] +) /$', 'SA. friends. views. accept_friend'),

(r'^friends/reject/ (? P<objid> [^/] +) /$', 'SA. friends. views. reject_friend'),

(r'^all_message/$', 'SA. friends. views. all_message'),

(r'^myfriends/$', 'SA. friends. views. my_friends'),

(r'^myfriends/sendmessage/ (? P<id> [^/] +) /$', 'SA. friends. views. send_message'),

(r'^blog/new_news/$', 'SA. blog. views. new_news'),

(r'^blog/blog_all_text/ (? P<id> [^/] +) /$', 'SA. blog. views. blog_all_text'),

(r'^blog/$', 'SA. blog. views. blog_views'),

(r'^blog/ (? P<slug> [^/] +) /$', 'SA. blog. views. blog_sort'),

(r'^blog/ (? P<year> [^/] +) / (? P<month> [^/] +) /$', 'SA. blog. views. blog_sort_date'),

)

Файл wsgi. py.

import os, sys

virtual_env = os. path. expanduser ('~/virtualenv/MyEnv')

activate_this = os. path. join (virtual_env, 'bin/activate_this. py')

execfile (activate_this, dict (__file__=activate_this))

sys. path. insert (0, os. path. join (os. path. expanduser ('~'), 'django/kurs2'))

os. environ ['DJANGO_SETTINGS_MODULE'] = 'SA. settings'

import django. core. handlers. wsgi

application = django. core. handlers. wsgi. WSGIHandler ()

Приложение В

Главный шаблон всего сайта supreme.html.

<! DOCTYPE html PUBLIC "- // W3C // DTD HTML 4.01 // EN"

"http://www.w3.org/TR/html4/strict. dtd">

{% load user_profile %}

<html xmlns="http://www.w3.org/1999/xhtml" lang="en">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>{% block title %}{% endblock %} Chat+++</title>

<link type="text/css" href="/media/yaml/core/base. css" rel="stylesheet">

<link type="text/css" href="/media/css/styles. css" rel="stylesheet">

<script type="text/javascript" src="/media/lib/jquery-1.7.1 min. js"></script>

<script type="text/javascript" src="/media/lib/balrog. js"></script>

<meta name="telderi" content="cba1d7c2e286711d42d0a79572178226" />

</head>

<body>

<div class="site_show_background_close">

</div>

<div class="ym-wrapper">

<div class="header">

<a href="/"><div class="logo">Chat+++</div></a>

{% if user. is_authenticated %}

<div class="registration_authenticated">

<ul>

<li><a class="reg" href="/accounts/profile/">Здравствуйте, <b>{{ user. username }}</b></a></li>

<li><a class="write" href="{% url auth_logout %}">Выйти из аккаунта</a></li>

<li><a href="{% url auth_password_change %}">Сменить пароль</a></li>

</ul>

</div>

{% else %}

<div class="registration">

<form method="post" action="/accounts/login/">

<ul>

{% csrf_token %}

<li>

<input type="text" class="reg_textfield textfield_email" name="username" value="Логин"/>

</li>

<li>

<input type="text" class="reg_textfield textfield_pass" name="password" value="Пароль"/>

</li>

<li>

<input class="joinbtn" type="submit" value="Войти"/>

</li>

<li>

<input class="registrationbtn" onClick="location. href='/accounts/register/'" type="button" value="Регистрация"/>

</li>

</ul>

</form>

</div>

{% endif %}

</div>

<div class="mainmenu {% if user. is_authenticated %}mainmenu_logon{% endif %}">

{% if user. is_authenticated %}

<div class="mainmenu_content_logon">

<ul>

<li><a href="/"><img src="/media/images/search. png"/><p>МОЯ СТРАНИЦА</p></a></li>

<li><a href="/blog/"><img src="/media/images/notes. png"/><p>НОВОСТИ</p></a></li>

<li><a href="/all_message/"><img src="/media/images/mail. png"/><p>СООБЩЕНИЯ {% if user. id|messages_count %} ({{ user. id|messages_count }}) {% endif %}</p></a>

</li>

<li><a href="/friends/"><img src="/media/images/profile. png"/><p>ДРУЗЬЯ</p></a></li>

</ul>

</div>

{% else %}

<div class="mainmenu_content">

<img src="/media/images/sitesimg. png"/>

<h2>Зарегестрируйтесь прежде чем пользоваться сайтом</h2>

</div>

{% endif %}

</div>

<div class="ym-column">

{% block title_site_info %}

{% endblock %}

<div class="ym-col1 {% block col1 %}{% endblock %}">

МЕСТО КУДА БУДЕТ ВЫВЕДЕН КОНТЕНТ ВСПЛЫВАЮЩИХ ОКОН

{% block main %}

{% endblock %}

</div>

<div class="ym-col3 {% block col3 %}{% endblock %}">

<div class="ym-cbox-right">

{% block right %}

{% endblock %}

</div>

</div>

</div>

</div>

</body>

</html>

Файл models. py приложения user_profile.

# - * - coding: utf-8 - *-

from django. db import models

from django. contrib. auth. models import User

from SA. user_profile. fields import AutoOneToOneField

import datetime

import Image

import datetime

import json

import mptt

import os. path

from SA. settings import *

class Profile (models. Model):

user = AutoOneToOneField (User, related_name='profile', verbose_name= ('User'), primary_key=True)

thumbnail = models. ImageField (verbose_name=u"Иконка", upload_to=u"photos/%Y/%m/%d", help_text=u'Загрузите картинку', blank=True)

requisites = models. TextField (verbose_name=u'Дополнительные сведения', blank=True)

login = models. CharField (max_length=150,verbose_name=u'Логин',blank=True)

last_name = models. CharField (max_length=150,verbose_name=u'Фамилия',blank=True)

first_name = models. CharField (max_length=150,verbose_name=u'Имя',blank=True)

midlle_name = models. CharField (max_length=150,verbose_name=u'Отчество',blank=True)

friends = models. ManyToManyField ("self", blank=True, symmetrical = False, related_name='friends_targets')

friend_requests = models. ManyToManyField ("self", blank=True, symmetrical = False, related_name='friend_requests_targets')

icq = models. CharField (max_length=150, verbose_name = u'ICQ', blank=True)

skype = models. CharField (max_length=150, verbose_name=u'Skype', blank = True)

telephone = models. CharField (max_length=150, verbose_name=u'Телефон', blank = True)

def __unicode__ (self):

return str (self. user)

def get_thumbnail_url (self, width, height):

"""Возвращает URL уменьшенной копии фотографии"""

try:

if not os. path. exists (self. thumbnail. path): return None

thumb_url = None

photo = str (self. thumbnail)

full_path_to_file = "%s/%s" % (MEDIA_ROOT, photo)

filename = self. thumbnail. path [self. thumbnail. path. rfind ("/") +1:]

upload_to = ""

path_to_thumbnail_dir = "%s/thumbnails%s/%sx%s" % (MEDIA_ROOT, upload_to, str (width), str (height))

if not os. path. exists (path_to_thumbnail_dir): os. makedirs (path_to_thumbnail_dir)

path_to_thumbnail = "%s/%s" % (path_to_thumbnail_dir, filename)

if not os. path. exists (path_to_thumbnail):

try:

image = Image. open (self. thumbnail. path)

image. thumbnail ( (width,height), Image. ANTIALIAS)

image. save (path_to_thumbnail, image. format, quality=95)

except:

return None

return "%sthumbnails/%s%sx%s/%s" % (MEDIA_URL, upload_to, str (width), str (height), filename)

except:

return ''

def get_thumbnail (self):

return self. get_thumbnail_url (100, "*")

def get_big (self):

return self. get_thumbnail_url (600, "*")

def get_min_thumbnail (self):

return self. get_thumbnail_url (45, "*")

class Message (models. Model):

recipient = models. ForeignKey (User, verbose_name=u'Получатель', related_name='recipients')

sender = models. ForeignKey (User, verbose_name=u'Отправитель', related_name='senders')

date = models. DateTimeField (verbose_name=u'Дата отправки сообщения',blank=True, null=True, default = datetime. datetime. now)

title = models. CharField (max_length=350,verbose_name=u'Заголовок сообщения',blank=True)

message = models. TextField (blank=True,verbose_name=u'Сообщение')

reader = models. BooleanField (blank=True,verbose_name=u'Сообщение отправлено')

class Chat (models. Model):

person1 = models. ForeignKey (User, verbose_name=u'Первый участник чата', related_name='persons1')

person2 = models. ForeignKey (User, verbose_name=u'Второй участник чата', related_name='persons2')

messages = models. ManyToManyField (Message, verbose_name=u'Все их сообщения', blank=True, related_name='all_message')

def last_message (self):

return self. messages. latest ('date')

Файл views. py для главной страницы и страницы настроек личной информации.

# - * - coding: utf-8 - *-

from SA. user_profile. models import Profile

from django. views. decorators. csrf import csrf_exempt

from django. shortcuts import render_to_response, redirect

from django. template import RequestContext # нужно чтобы передавать реквест в контекст

from django. forms import ModelForm

from django. http import HttpResponse, HttpResponseRedirect

from django import forms

from django. db. models import Q

from django. contrib. auth. models import User

import datetime

import time

@csrf_exempt

def my_profile (request):

# выводим все данные

ERROR = None

if request. user. is_authenticated ():

vector = User. objects. get (pk = request. user. id)

if Profile. objects. get (pk=request. user. id):

object = Profile. objects. get (pk = request. user. id)

else:

object = Profile ()

object. user_id = vector. id

object. first_name = vector. first_name

object. last_name = vector. last_name

object. save ()

context = {'person': object}

return render_to_response ("kurs/my_profile.html", context, context_instance=RequestContext (request))

else:

# если не залогинен

# хорошо бы сделать из этой проверки декоратор, чтоб всюду её не тоскать за собой

return render_to_response ("kurs/error.html", {'ErrorText': u"Вы не авторизированны"}, context_instance=RequestContext (request))

@csrf_exempt

def user_settings (request):

ERROR = None

if request. user. is_authenticated ():

class ProfileForm (ModelForm):

class Meta:

model = Profile

exclude = ('user', 'friends', 'friend_requests')

new_password = forms. CharField (max_length=150, required=False,label='Новый пароль')

confirm_password = forms. CharField (max_length=150, required=False,label='Подтвердить пароль')

user_id = request. user. id

if request. method == 'POST':

object = Profile. objects. get (pk = user_id)

form = ProfileForm (request. POST, request. FILES, instance = object)

if form. is_valid ():

new_password = form. cleaned_data ['new_password']

confirm_password = form. cleaned_data ['confirm_password']

index = User. objects. get (pk = request. user. id)

index. set_password (new_password)

if new_password == '':

str = 'Поле (новый пароль) пусто: '

else:

if confirm_password == new_password:

str = 'Пароли совпадают! '

index. save ()

else:

str = 'Пароли не совпадают! '

form. save ()

context = {'form': form, 'error': str, 'object': object}

return render_to_response ("kurs/user_settings.html", context, context_instance=RequestContext (request))

else:

form = ProfileForm ()

object = Profile. objects. get (pk = user_id)

form = ProfileForm (instance = object)

context = {'form': form, 'object': object}

return render_to_response ('kurs/user_settings.html', context, context_instance=RequestContext (request))

else:

# если не залогинен

# хорошо бы сделать из этой проверки декоратор, чтоб всюду её не тоскать за собой

return render_to_response ("user_profile/error.html", {'ErrorText': u"Вы не авторизированны"})

Шаблон error.html для вывода ошибки если пользователь не зарегистрирован.

{% extends "main.html" %}

{% block main %}

<div class="left_site_registration">

<h2>Ошибка</h2>

{{ErrorText|safe}}

</div>

{% endblock %}

Шаблон my_profile.html для вывода личной информации пользователя.

{% extends "main.html" %}

{% block main %}

<div class="left_col_profile_block">

<form enctype="multipart/form-data">

<table>

<tr>

<td>

{% if person. thumbnail == "" %}

<img src="/media/images/default. png"/>

{% else %}

<img id="img-{{ person. thumbnail }}" src="{{ MEDIA_URL }}{{ person. thumbnail }}"/>

{% endif %}

</td>

</tr>

<tr>

<td><p class="right_col_form_contragent_blue">О себе: </p></td> <td><p>{{ person. requisites }}</p></td>

</tr>

<tr>

<td><p class="right_col_form_contragent_blue">Фамилия: </p></td> <td><p>{{ person. last_name }}</p></td>

</tr>

<tr>

<td><p class="right_col_form_contragent_blue">Имя: </p></td> <td><p>{{ person. first_name }}</p></td>

</tr>

<tr>

<td><p class="right_col_form_contragent_blue">Отчество: </p></td> <td><p>{{ person. midlle_name }}</p></td>

</tr>

<tr>

<td><p class="right_col_form_contragent_blue">Телефон: </p></td> <td><p>{{ person. telephone }}</p></td>

</tr>

<tr>

<td><p class="right_col_form_contragent_blue">Skype: </p></td> <td><p>{{ person. skype }}</p></td>

</tr>

<tr>

<td><p class="right_col_form_contragent_blue">ICQ: </p></td> <td><p>{{ person. icq }}</p></td>

</tr>

</table>

<u><a class="right_col_form_contragent_blue" href="/person/user_settings/">Настройки</a></u>

</form>

</div>

{% endblock %}

Шаблон user_settings.html для вывода страницы настроек личной информации.

{% extends "main.html" %}

{% block main %}

<div class="left_col_profile_block">

<h2>Профиль пользователя {{user. username}}</h2>

{% if form. thumbnail. value %}

<img id="img-{{ object. thumbnail }}" src="{{object. get_thumbnail }}"/>

{% else %}

<img src="/media/images/default. png"/>

{% endif %}

<form enctype="multipart/form-data" action="" method="post">

<p>{{form. thumbnail}}</p>

<h4>Дополнительные сведения</h4>

<p>{{form. requisites}}</p>

<h4>Контактные данные</h4>

<p>{{form. user. label}}{{form. user}}</p>

<p>{{form. first_name. label}}{{form. first_name}}</p>

<p>{{form. last_name. label}}{{form. last_name}}</p>

<p>{{form. midlle_name. label}}{{form. midlle_name}}</p>

<p>{{form. icq. label}}{{form. icq}}</p>

<p>{{form. skype. label}}{{form. skype}}</p>

<p>{{form. telephone. label}}{{form. telephone}}</p>

<p>{{form. new_password. label}}{{form. new_password}}</p>

<p>{{form. confirm_password. label}}{{form. confirm_password}}</p>

{{error}}

<input class="left_col_profile_block_accept_button" type="submit" value="Сохранить">

</form>

</div>

{% endblock %}

{% block right %}

{% endblock %}

Шаблонный тег для вывода количества новых сообщений.

# - * - coding: utf-8 - *-

from django. template import Library

from django. db. models import Q

from SA. user_profile. models import Message

from django. contrib. auth. models import User

register = Library ()

@register. filter

def messages_count (obj):

i_am = User. objects. get (pk = obj)

messages = Message. objects. filter (recipient = i_am). filter (reader = False). count ()

return messages

Файл views. py обрабатывающий страницу ДРУЗЬЯ и СООБЩЕНИЯ.

# - * - coding: utf-8 - *-

from SA. user_profile. models import Profile, Message, Chat

from django. views. decorators. csrf import csrf_exempt

from django. template import RequestContext # нужно чтобы передавать реквест в контекст

from django. forms import ModelForm

from django. http import HttpResponse, HttpResponseRedirect

from django import forms

from django. db. models import Q

from django. shortcuts import render_to_response, redirect

from django. contrib. auth. models import User

import datetime

import time

# Передача на страницу формы поиска и осуществление самого поиска.

# Вывод искомых пользователей

@csrf_exempt

def search_person (request):

ERROR = None

if request. user. is_authenticated ():

class ContactForm (forms. Form):

last_name = forms. CharField (max_length=150, required=False)

first_name = forms. CharField (max_length=150, required=False)

user = forms. CharField (max_length=150, required=False)

midlle_name = forms. CharField (max_length=150, required=False)

current_user = request. user. get_profile

if request. method == 'POST':

form = ContactForm (request. POST)

params = []

if form. is_valid ():

last_name = form. cleaned_data ['last_name']

first_name = form. cleaned_data ['first_name']

midlle_name = form. cleaned_data ['midlle_name']

user = form. cleaned_data ['user']

kargs = {'last_name__icontains': last_name}

params. append (apply (Q, (), kargs))

params. append (Q (first_name__icontains = first_name))

params. append (Q (midlle_name__icontains = midlle_name))

params. append (Q (user__username__icontains = user))

search_result = Profile. objects. filter (*params)

context = {'form': form, 'search_result': search_result, 'User': current_user}

return render_to_response ('friends/search_person.html', context, context_instance=RequestContext (request))

else:

form = ContactForm ()

context = {'form': form, 'User': current_user}

return render_to_response ('friends/search_person.html', context, context_instance=RequestContext (request))

else:

# если не залогинен

# хорошо бы сделать из этой проверки декоратор, чтоб всюду её не тоскать за собой

return render_to_response ("friends/error.html", {'ErrorText': u"Вы не авторизированны"})

# Прохождение по ссылке "Добавить в друзья"

def add_person (request, id):

obj = Profile. objects. get (user = id)

user = Profile. objects. get (user = request. user. get_profile)

user. friends. add (obj)

obj. friend_requests. add (user)

return HttpResponseRedirect ('/friends/')

# Прохождение по ссылке "Удалить друга"

def del_person (request, id):

obj = Profile. objects. get (user = id)

user = Profile. objects. get (user = request. user. get_profile)

user. friends. remove (obj)

return HttpResponseRedirect ('/friends/')

#Прохождение по ссылке "Принять друга"

def accept_friend (request, objid):

obj = Profile. objects. get (user= request. user. get_profile)

obj_friend = Profile. objects. get (user = objid)

obj. friends. add (obj_friend)

obj. friend_requests. remove (obj_friend)

return HttpResponseRedirect ('/friends/')

# Прохождение по ссылке отклонить друга

def reject_friend (request, objid):

obj = Profile. objects. get (user = request. user. get_profile)

obj_friend = Profile. objects. get (user = objid)

obj. friend_requests. remove (obj_friend)

return HttpResponseRedirect ('/friends/')

# Вывод всех друзей

@csrf_exempt

def my_friends (request):

ERROR = None

if request. user. is_authenticated ():

friends = User. objects. all ()

if request. method == 'POST':

pass

context = {'friends': friends}

return render_to_response ('friends/choice_friend.html', context, context_instance=RequestContext (request))

else:

# если не залогинен

# хорошо бы сделать из этой проверки декоратор, чтоб всюду её не тоскать за собой

return render_to_response ("friends/error.html", {'ErrorText': u"Вы не авторизированны"})

# Вывод объектов моделей Chat и Message

@csrf_exempt

def all_message (request):

ERROR = None

if request. user. is_authenticated ():

i_am = User. objects. get (pk = request. user. id)

temp4 = Q (person2 = i_am)

temp5 = Q (person1 = i_am)

all_friend = Chat. objects. filter (temp4 | temp5) #person1 = request. user. username or person2 = request. user. username)

i_am = User. objects. get (pk = request. user. id)

messages = Message. objects. filter (recipient = i_am). filter (reader = False). count ()

image = all_friend

#Передаем в шаблон объект чата, что бы определить каким цветом обозначать собеседника

context = {'all_friend': all_friend, 'messages': messages, 'image': image}

return render_to_response ('friends/all_message.html', context, context_instance=RequestContext (request))


Подобные документы

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.