РАЗРАБОТКА АРХИЕТКТУРЫ ВЕБ-СЕРВИСА ЗАКРЫТОЙ СОЦИАЛЬНОЙ СЕТИ С ИСПОЛЬЗОВАНИЕМ ФРЕЙМВОРКА DJANGO

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

2015-08-27

606.29 KB

15 чел.


Поделитесь работой в социальных сетях

Если эта работа Вам не подошла внизу страницы есть список похожих работ. Так же Вы можете воспользоваться кнопкой поиск


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

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

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

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

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

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

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

С. Е. Рубцов

_________________________

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

РАЗРАБОТКА АРХИЕТКТУРЫ ВЕБ-СЕРВИСА ЗАКРЫТОЙ СОЦИАЛЬНОЙ СЕТИ  С ИСПОЛЬЗОВАНИЕМ ФРЕЙМВОРКА DJANGO

Работу выполнила студентка 4-го курса факультета компьютерных технологий и прикладной математики спец. 010501 – Прикладная математика и информатика

           Михно В. Д.

Краснодар – 2013

СОДЕРЖАНИЕ

ВВЕДЕНИЕ……………………………………………………………………………3

  1.  Анализ закрытых социальных сетей……………………………………………5
  2.  Постановка задачи………………………………………………………………..8
  3.  Структура web-приложения..…………………..………………………………..9
    1.  База данных и административная часть …………………………………10
    2.  Логическая часть приложения и отображение данных на страницах…13

ЗАКЛЮЧЕНИЕ…………………………………………………………………........20

СПИСОК ИСПОЛЬЗУЕМЫХ ИСТОЧНИКОВ………………………………..…21

ПРИЛОЖЕНИЕ А……………………………………………………………………22

ПРИЛОЖЕНИЕ В……………………………………………………………………29


ВВЕДЕНИЕ

В настоящее время количество социальных сетей в Интернете и численность их участников растет с невероятной быстротой. Социальные сети уже сегодня посещает более чем две трети онлайн-аудитории во всем мире, и это четвертая по популярности онлайн-категория после поисковых порталов, информационных порталов и программного обеспечения, которая опережает даже электронную почту (по данным компании 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 человек профессиональных юристов, объединенных Федеральным Законом "Об адвокатской деятельности и адвокатуре в Российской Федерации", кодексом профессиональной этики адвоката. Каждый адвокат, пришедший в сеть, чувствует родную среду, плечо коллеги, единство интересов и профессионализм.

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

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

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

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


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

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

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

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

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

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

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


  1.  Структура 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., можем переходить к той части проекта, которая будет отвечать за функционал нашего сайта.

 


  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, поэтому не будем останавливаться на них. Они представлены в ПРИЛОЖЕНИИ В.


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

Функционал главной страницы представлен двумя функциями 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 - Страница с моими друзьями и возможностью поиска новых.

Теперь рассмотрим функционал обмена сообщениями. При прохождении в меню  по ссылки СООБЩЕНИЯ мы попадаем на страницу где показаны лишь чаты и их последние объекты из поля ManyToManyFieldmessages (Рис. 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="files/2//media/lib/jquery-1.7.1.min.js"></script>

 <script type="text/javascript" src="files/2//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="files/2//media/images/search.png"/><p>МОЯ СТРАНИЦА</p></a></li>

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

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

    </li>

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

   </ul>

  </div>

  {% else %}

  <div class="mainmenu_content">

   <img src="files/2//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="files/2//media/images/default.png"/>

 {% else %}

  <img id="img-{{ person.thumbnail }}" src="files/2/{{ 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="files/2/{{object.get_thumbnail }}"/>

 {% else %}

  <img src="files/2//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))

   else:

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

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

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

       

# Вывод формы для отправки сообщения

@csrf_exempt

def send_message(request, id):

   class MessageForm(forms.Form):

       title = forms.CharField(max_length=350, required=False)

       message = forms.CharField(max_length=350, required=False, widget=forms.Textarea)

   

   #Выбираем отправить личное сообщение, и определяем в бд, что я - покупатель,а тот кому пишу письмо - продавец

           

   friend = User.objects.get(pk = id)

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

   

   temp1 = Q(recipient = friend) & Q(sender = i_am)

   temp2 = Q(recipient = i_am) & Q(sender = friend)

   temp3 = temp1 | temp2

   

   temp4 = Q(person2 = i_am) & Q(person1 = friend)

   temp5 = Q(person1 = i_am) & Q(person2 = friend)

   #Выбрали - отправить личное сообщение, и определяем в бд, что я - person1 и покупатель,а тот кому пишу письмо - person2 и продавец

   if len(Chat.objects.filter(temp4 | temp5)) == 0:

       chat = Chat()

       chat.person1 = i_am

       chat.person2 = friend

       chat.save()

   else:

       pass

           

   if request.method == 'POST':

       

       all_message = Message.objects.filter(temp3).order_by('date')

               

       chat_obj = Chat.objects.get(temp4 | temp5)

       form = MessageForm(request.POST)

       if form.is_valid():

           title = form.cleaned_data['title']

           message = form.cleaned_data['message']

           send_message = Message()

           send_message.recipient = friend

           send_message.sender = i_am

           send_message.date = datetime.datetime.now()

           send_message.title = title

           send_message.message = message

           #for elem in send_message:

           send_message.reader = False

           send_message.save()

           chat_obj.messages.add(send_message)

           chat_obj.save()

           

       return redirect('/myfriends/sendmessage/'+ str(id) + '/')

   else:       

       all_message = Message.objects.filter(temp3).order_by('date')[0::1]

       temp4 = Q(person2 = i_am) & Q(person1 = friend)

       temp5 = Q(person1 = i_am) & Q(person2 = friend)

       person_type = Chat.objects.filter(temp4 | temp5)

       form = MessageForm()

       #Если чувак открыл весь чат, то это значит, что он все сообщения уже прочел

       # Которые находятся в переписке => они все устанавливаются в false

       send = Message.objects.filter(temp2)

       for elem in send:

           if not elem.reader:

               elem.reader=True

               elem.save()

       context = {'form':form, 'friend': friend, 'all_message': all_message}

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

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

{% extends "main.html" %}

{% block main %}

<div class="left_site_registration">

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

{{ErrorText|safe}}

</div>

{% endblock %}

Шаблон search_person.html для вывода поисковой формы и всех добавленных или тех кто хочет добавиться в друзья

{% extends "main.html" %}

{% block main %}

<div class="right_col_form_contragents">

<h1>Поиск друзей</h1>

<form action="" method="post">

<p class="right_col_form_contragent_log_firm">Фамилия: {{ form.last_name }}</p>  

<p class="right_col_form_contragent_log_firm">Имя: {{ form.first_name }}</p>  

<p class="right_col_form_contragent_log_firm">Отчество: {{ form.midlle_name }}</p>

<p class="right_col_form_contragent_log_firm">Логин: {{ form.user }}</p>

<input class="right_col_btn" type="submit" value="ПОИСК">

{% for obj in search_result %}

 {% if User != obj  %}

  <p>{{ obj.last_name }}  {{obj.first_name}}  {{obj.midlle_name}} {{ obj.user }}</p>

   {% if obj in User.friends.all %}

    <p>Уже ваш друг!</p>

   {% else %}

       <p><a class="right_col_form_contragent_blue" href="/friends/add/{{ obj.user.id }}/">Добавить в друзья</a></p>

      {% endif %}

 {% endif %}

{% endfor %}

 

{% if User.friends.all %}

<h2>Мои друзья:</h2>

 {% for elem in  User.friends.all %}

  <p>{{ elem }}</p>

  <p><a class="right_col_form_contragent_blue" href="/friends/del/{{ elem.user.id }}/">Удалить из друзей</a></p>

  <p><a class="right_col_form_contragent_blue" href="/myfriends/sendmessage/{{ elem.user.id }}/">Написать сообщение</a></p>

 {% endfor %}

{% endif %}

{% if User.friend_requests.all %}

 <h2>К вам хотят добавиться:</h2>

 {% for obj in User.friend_requests.all %}

  <p>{{ obj }}</p>

  <p><a class="right_col_form_contragent_blue" href="/friends/accept/{{ obj.user.id }}/">Принять друга</a></p>

  <p><a class="right_col_form_contragent_blue" href="/friends/reject/{{ obj.user.id }}/">Отклонить друга</a></p>

 {% endfor %}

{% endif %}

</form>

</div>

{% endblock %}

Шаблон all_message.html для вывода всех сообщений

{% extends "main.html" %}

{% block main %}

<form action="" method="post">

<table class="leftcol_site_list">

<tr class="title_table_left_col">

 <td colspan="2">Сообщения</td>

</tr>

{% for elem in all_friend %}

<tr class="right_col_table_message_list {% cycle '' 'tr_blue_color' %}">

 <td>

 <a href="/myfriends/sendmessage/{% if request.user.id == elem.person1.id %}{{elem.person2.id}}{% else %}

 {{elem.person1.id}}{% endif %}/">

 {% if request.user.id == elem.person1.id %}

  {% if elem.person2.thumbnail == "" %}

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

  {% else %}

   <img id="img-{{ elem.person2.get_min_thumbnail }}" src="files/2/{{ elem.person2.get_min_thumbnail }}"/>

  {% endif %}

 {% else %}

  {% if elem.person1.thumbnail == "" %}

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

  {% else %}

   <img id="img-{{ elem.person1.get_min_thumbnail }}" src="files/2/{{ elem.person1.get_min_thumbnail }}"/>

  {% endif %}

 {%endif%}

{% if user.id == elem.person2.id %}

  <p>{{ elem.person1 }}</p>

{% else %}

       <p>{{ elem.person2 }}</p>

 {% endif %}

 <div>{{ elem.last_message.date }}</div>

 </a>

 </td>

 <td>

 <a href="/myfriends/sendmessage/{% if request.user.id == elem.person1.id %}{{elem.person2.id}}{% else %}

 {{elem.person1.id}}{% endif %}/">

 <p>{{ elem.last_message.message|truncatechars:80 }}</p>

 </a>

 </td>

</tr>

{% endfor %}

</table>

</form>

{% endblock %}

Шаблон send_message.html, для вывода всего чата и формы для отправки нового сообщения.

{% extends "main.html" %}

{% block main %}

<div class="left_col_mail">

<form action="" method="post">

<table class="leftcol_site_list">

<tr class="title_table_left_col">

 <td>История сообщений</td>

</tr>

{% for elem in all_message %}

{% if elem.reader %}

 <tr bgcolor="#F8F8FF">

{% else %}

 <tr bgcolor="#B2DFEE">

{% endif %}

 <td class="left_col_mail_message_block">

 <div>{{ elem.date }}</div>

 <b>

  {{ elem.sender }}

  <br />

  {{ elem.title }}

 </b>

 <p>{{ elem.message }}</p>

 </td>

</tr>

{% endfor %}

</table>

<p>Кому: {{ friend.username }}</p>

<p>Заголовок:</p>

<div>{{ form.title }}</div>

<p>Сообщение:</p>

<div>{{ form.message }}</div>

<input class="left_col_profile_block_accept_button" type="submit" value="Отправить">

</form>

</div>

{% block right %}

{% endblock %}

{% endblock %}

Модель приложения НОВОСТИ models.py

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

from django.db import models

from django.contrib.auth.models import User

import datetime

class Comment(models.Model):

   name = models.CharField(max_length=350,verbose_name=u'Имя отправителя комментария',blank=True)

   mail = models.EmailField(max_length=350,verbose_name=u'E-mail',blank=True)

   site = models.URLField(max_length=350,verbose_name=u'Адрес сайта',blank=True, verify_exists=False)

   comment = models.TextField(verbose_name=u'Комментарий', blank=True)

   

class Rubrics(models.Model):

   title = models.CharField(max_length=350,verbose_name=u'Заголовок рубрики',blank=True)

   slug = models.CharField(max_length=350, verbose_name=u'Перевод на английский')

   

   def __unicode__(self):

       return self.title

      

class Blog(models.Model):

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

   text_before = models.TextField(verbose_name=u'Начало новости', blank=True)

   text_after = models.TextField(verbose_name=u'Окончание новости', blank=True)

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

   rubrics = models.ManyToManyField(Rubrics, verbose_name=u'Рубрики', related_name='rubric', blank=True, null=True)

   comments = models.ManyToManyField(Comment, verbose_name=u'Комментарии', related_name='comments', blank=True, null=True)

   def __unicode__(self):

       return self.title

Файл views.py для отображения данных на странице НОВОСТИ

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

from SA.blog.models import Blog, Rubrics, Comment

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 blog_views(request):

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

   ERROR = None

   if request.user.is_authenticated():

       news = Blog.objects.all()

       rubric = Rubrics.objects.all()

       date_obj = []

       for obj in Blog.objects.dates('date', 'month'):

           date_obj.append(obj.date)

       context = {'news':news, 'rubric':rubric, 'date_obj':date_obj }

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

   else:

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

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

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

   

@csrf_exempt

def new_news(request):

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

   ERROR = None

   if request.user.is_authenticated():

       class BlogForm(forms.Form):

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

           text_before = forms.CharField(max_length=350, required=False, widget=forms.Textarea)

           text_after = forms.CharField(max_length=350, required=False, widget=forms.Textarea)

       if request.method == 'POST':

           form = BlogForm(request.POST)

           if form.is_valid():

               title = form.cleaned_data['title']

               text_before = form.cleaned_data['text_before']

               text_after = form.cleaned_data['text_after']

               new = Blog()

               new.title = title

               new.text_before = text_before

               new.text_after = text_after

               new.date = datetime.datetime.now()

               #for elem in send_message:

               new.save()

           

           return redirect('/blog/')

       else:

           form = BlogForm()

           context = {'form':form}

           return render_to_response('blog/new_news.html', context, context_instance=RequestContext(request))

   else:

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

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

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

@csrf_exempt

def blog_sort(request, slug):

   news = Blog.objects.filter(rubrics__slug=slug)

   rubric = Rubrics.objects.all()

   date_obj = []

   for obj in Blog.objects.dates('date', 'month'):

       date_obj.append(obj.date)            

   context = {'news':news, 'rubric':rubric,  'date_obj':date_obj}

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

@csrf_exempt

def blog_sort_date(request, year, month):

   news = Blog.objects.filter(date__year=year).filter(date__month=month)

   rubric = Rubrics.objects.all()

   date_obj = []

   for obj in Blog.objects.dates('date', 'month'):

       date_obj.append(obj.date)            

   context = {'news':news, 'rubric':rubric, 'date_obj':date_obj}

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

@csrf_exempt

def blog_all_text(request, id):

   ERROR = None

   if request.user.is_authenticated():

       class CommentForm(forms.Form):

           name_user = forms.CharField(max_length=150, required=False, initial = request.user.username)

           mail = forms.EmailField(max_length=150, initial=request.user.email)

           site = forms.URLField(max_length=150, required=False, verify_exists=False)

           comment = forms.CharField(max_length=350, required=False, widget=forms.Textarea)

       date_obj = []

       for obj in Blog.objects.dates('date', 'month'):

           date_obj.append(obj.date)           

       if request.method == 'POST':

       # Выберем тот объект из модели Blog, которой хотим отправить комментарий

           this_new = Blog.objects.get(id = id)

           form = CommentForm(request.POST)

           if form.is_valid():

               name_user = form.cleaned_data['name_user']

               mail = form.cleaned_data['mail']

               site = form.cleaned_data['site']

               comment = form.cleaned_data['comment']

               

               model_comment = Comment()

               model_comment.name = name_user

               model_comment.mail = mail

               model_comment.site = site

               model_comment.comment = comment

               model_comment.save()

               # Добавляем в новость которую мы сейчас просматриваем новый комментарий

               

               this_new.comments.add(model_comment)

               this_new.save()

           return redirect('/blog/blog_all_text/'+ str(id) + '/')

       else:    

           form = CommentForm()

           news = Blog.objects.get(id = id)

           rubric = Rubrics.objects.all()

           context = {'form': form, 'news':news, 'rubric':rubric, 'date_obj':date_obj}

           return render_to_response("blog/blog_all_text.html", context, context_instance=RequestContext(request))

   else:

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

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

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

Шаблон blog.html для главной страницы приложения НОВОСТИ

{% extends "main.html" %}

{% block main %}

<div class="left_col_profile_block">

<form action="" method="post">

Архивы:

{% for obj in date_obj %}

<p><a class="right_col_form_contragent_blue" href="/blog/{{ obj|date:"Y" }}/{{ obj|date:"n" }}">{{ obj|date:"F Y" }}</a></p>

{% endfor %}

<p>_________________________________________________________</p>

<table width="100%" border="0" cellspacing="0" cellpadding="4">

{% for elem in news %}

 <tr align="center" bgcolor="#B2DFEE"><p> {{ elem.title }} </p></tr>

 

<tr align="center">

<p>                                                         </p>

<p>{{ elem.text_before }}</p></tr>

 

<tr align="center">

<p><a class="right_col_form_contragent_blue" href="/blog/blog_all_text/{{ elem.id }}/"> Читать полностью >> </a></p>

</tr>

<tr align="center"><p> {{ elem.date}} </p></tr>

{% endfor %}

</table>

<a class="right_col_form_contragent_blue" href="/blog/new_news/">Отправить сообщение</a>

</form>

</div>

{% endblock %}

Шаблон blog_all_text.html для просмотра всего текста новости и возможности написания комментария.

{% extends "main.html" %}

{% block main %}

<div>

<form action="" method="post">

Архивы:

{% for obj in date_obj %}

<p><a class="right_col_form_contragent_blue" href="/blog/{{ obj|date:"Y" }}/{{ obj|date:"n" }}">{{ obj|date:"F Y" }}</a></p>

{% endfor %}

<p>_________________________________________________________</p>

<table width="100%" border="0" cellspacing="0" cellpadding="4">

 <tr align="center" bgcolor="#B2DFEE"><p> {{ news.title }} </p></tr>

 

<tr align="center">

<p> {{ news.text_before }} </p>

</tr>

 

<tr align="center">

<p> {{ news.text_after }} </p>

</tr>  

<tr align="center"><p> {{ news.date }}</p></tr>

</table>

<table class="leftcol_site_list">

<tr class="title_table_left_col">

 <td colspan="2">Комментарии</td>

</tr>

{% for obj in news.comments.all %}

<tr class="right_col_table_message_list {% cycle '' 'tr_blue_color' %}">

<td align="center"> {{ obj.name }}</td>

<td> {{ obj.comment }}</td>

</tr>

{% endfor %}

</table>

<table>

<tr><td> Имя: {{ form.name_user }}</td></tr>

<tr><td> Комментарии: {{ form.comment }}</td></tr>

</table>

<input type="submit" value="Отправить">

</form>

</div>

{% endblock %}

Шаблон new_news.html для опубликования новой новости.

{% extends "main.html" %}

{% block main %}

<div class="left_col_profile_block">

<h2>Новая запись</h2>

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

<form action="" method="post">

 

<h4>Заголовок</h4>

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

 <h4>Первая часть новости</h4>

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

 <h4>Вторая часть новости</h4>

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

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

</form>

</div>

{% endblock %}

   

   

 



 

Другие похожие работы, которые могут вас заинтересовать.
7398. РАЗРАБОТКА АРХИТЕКТУРЫ ЗАКРЫТОЙ КОРПОРАТИВНОЙ СЕТИ С ИСПОЛЬЗОВАНИЕМ ФРЕЙМВОРКА DJANGO 1.39 MB
  С помощью свободно распространяемого фреймворка Django для веб-приложений, на языке Python, разработать веб-приложение, для фирмы ККМОО «Молодежная лига развития национальных культур Кубани», реализующее четвертый и пятый разделы технического задания; реализовать главную страница пользователя, возможность загружать документы себе на страницу
3612. Разработка проекта мультисервисной сети, выбор технологии сети, разработка ее структуры, установка оборудования и расчет его комплектации 6.93 MB
  В данном дипломном проекте решена задача построения мультисервисной сети широкополосной передачи данных для предоставления услуги Triple Play, на основе технологии FTTB. Проведен анализ исходных данных. Предложено обоснование выбранной технологии и топологии сети, проведен расчет оборудования а также подбор его комплектации, расчет нагрузки на сеть, приведены технико-экономические показатели, разработаны мероприятия по безопасности жизнедеятельности.
17413. Разработка фирменного стиля салона ногтевого сервиса «Viality» 1.72 MB
  Выбор именно фирменного стиля салонов красоты в качестве объекта исследования обусловлен тем, что в настоящее время салон красоты – это и бизнес, и место отдыха, и комплексное средство ухода за внешностью, и медицинская помощь телу, поэтому именно в этой сфере услуг нужна грамотная и эффективная реклама. Кроме того, уровень конкуренции на рынке этих услуг так велик, что компаниям сложно отстроиться от конкурентов.
12492. Разработка учебной дизайн - лаборатории парикмахерского сервиса при УГУЭС для создания молодежного стиля 3.6 MB
  Профессию парикмахера нельзя назвать редкой, в нашей стране она достаточно распространена. Уже несколько лет на рынке труда наблюдается спрос на представителей профессии парикмахера, несмотря на то, что специалистов каждый год выпускается немало. Парикмахеры работают в салонах красоты, парикмахерских, рекламных и модельных агентствах, на телевидении. Карьерный рост специалиста зависит от его мастерства и профессионализма.
13316. Проектирование участка оптической транспортной сети МО между городами Балашиха – Орехово-Зуево с использованием оборудования технологии SDH 578.17 KB
  В настоящее время ускорение технического прогресса невозможно без совершенствования средств связи систем сбора передачи и обработки информации. В вопросах развития сетей связи во всех странах большое внимание уделяется развитию систем передачи и распределения коммутации информации. Наиболее широкое распространение в последнее время получили многоканальные телекоммуникационные системы ТКС передачи с импульснокодовой модуляцией ИКМ работающие по волоконнооптическим кабелям ОК. Дальнейшему развитию методов и аппаратуры...
14059. Употребления сленга в среде современного молодежного общения - социальной сети Facebook 380.37 KB
  Сленг, как и остальная лексика, меняется каждый день. Особенно с появлением новых технологий, субкультур, определенной моды. Так, в работах по изучению сленга тридцать, двадцать, десять лет назад мы находим, во-первых, слова давно ушедшие из употребления
15075. Соблюдение современных норм русского языка в зависимости от коммуникативной ситуации в социальной сети «ВКонтакте» 2.47 MB
  Тема данного исследования затрагивает область интернет-лингвистики. С появлением нового пространства для общения начинается возникновение новых форм употребления и использования языка, которые очень быстро складываются и изменяются. Из-за быстрых темпов развития и накопления информации на просторах Сети ученые, занимающиеся исследованием интернет-коммуникации
17331. Разработка мехатронной системы ориентирования с использованием SLAM технологии 2.33 MB
  Техническое задание для ВКР было сформировано предприятием заказчиком. При этом необходимо не только определение собственного положения но и запоминание и сохранение изображения окружающего пространства для областей информации о которых нет в памяти робота. Так же необходимо предотвращение столкновений робота с окружающими предметами для этого эффективно использовать дальномеры. Исследовательская часть Обзор существующих решений Наиболее передовые алгоритмы используют изображение с веб-камер и дальномеров для определения положения...
1514. Разработка локальной сети предприятия 730.21 KB
  Цель данной работы – используя имеющиеся требования к сети и имеющие специфики здания, организовать наиболее оптимальную с точки зрения цены/качества сеть, удовлетворяющую характеристикам, представленным выше.
1815. Разработка районной сети электроэнергии 359.97 KB
  Данный проект включает в себя следующие разделы: введение в котором формулируем цель проекта устанавливаем связь принимаемых решений с задачами проектирования и эксплуатации других объектов обосновываем актуальность разрабатываемой темы проекта; баланс мощности в энергосистеме в результате которого определяем мощность компенсирующих устройств каждой подстанции; шесть первоначальных вариантов проектируемой сети; выбор напряжения конструкции линий подстанций сопоставление и отбор наиболее оптимального варианта; электрический...
© "REFLEADER" http://refleader.ru/
Все права на сайт и размещенные работы
защищены законом об авторском праве.