среда, 20 апреля 2011 г.

Журналирование/логирование


Ниже представлена слегка переделанная функция, взятая вот отсюда:  http://pysi.org/articles/django_and_tornado/
views.py:
 

def userlogpath(user, message):
  #создание директории для записи лога и файла лога
  LOG_DIR = MEDIA_ROOT+'/log'
  LOG_FILE =  LOG_DIR+username+'.log'

  #проверка существования директории (впервые вошел в систему)
  if not os.path.isdir(LOG_DIR):
    os.makedirs(LOG_DIR)


  #задаем свойсива файла логирования
  #вданнои случе его размкщение
  file_handler = logging.handlers.RotatingFileHandler(
    filename = LOG_FILE)#, mode='a+', # имя файла
   #maxBytes = 1000000, # максимально байт в файле
   #backupCount = 1) # максимум файлов

  # задаем режим логирования ('INFO')
  file_handler.setLevel(getattr(logging, 'INFO'))
  #задаем формат логирования (число-месяц-год время) 
  file_handler.setFormatter(
  logging.Formatter('%(asctime)s\t%(levelname)-8s %(message)s',
                               datefmt = '%d-%m-%Y %H:%M:%S'))
  logging.getLogger('').setLevel(logging.INFO)
  #устанавливаем режим добавления в файл
  logging.getLogger('').addHandler(file_handler)

  #записываем информацию
  logging.info(message)

  #закрываем файл
  logging.getLogger('').removeHandler(file_handler)
  file_handler.close()


Это был простой способ. Но можно повыпендриваться и записать основные директории в settings.py, например вот так:

LOG_DIRNAME = 'log'
LOG_DIR = os.path.join( '{user}', LOG_DIRNAME)
LOG_FILENAME = '{user}.log'
LOG_FILE_PATH = os.path.join(MEDIA_ROOT, LOG_DIR, LOG_FILENAME)

#в views.py вызвать вот так:

LOG_FILE = settings.LOG_FILE_PATH.format(user=user.username)
LOG_DIR = os.path.dirname(LOG_FILE)

воскресенье, 17 апреля 2011 г.

Авторизация средствами Django


  В Django есть две таблицы. Это User и Group. Они располагаются в django.contrib.auth. На самом деле там есть еще таблицы, но для создания проверки прав доступа, необходимы эти две.
  В таблице Group, будут содержаться группы пользователей, которые имеют различные правадоступа. В данном случае это:

1. Оператор
2. Пользователь (Юзер)

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

  Для работы с этими таблицами необходимо их импортировать:

from django.contrib.auth.models import User, Group

  Далее, при первичной аутоидентификации, данные вносятся в таблици:
# выполняется в блоке try - except, если таблица была пустой и туда ещё не
# вносились записи

try:
    group = Group.objects.get(name='user')
except Group.DoesNotExist:
# вексение групп пользователей
    group = Group(name='operators')
    group.save()
    group = Group(name='users')
    group.save()
try:
    user = User.objects.get(username=username)
except User.DoesNotExist:
# создание записи пользователя
    user = User.objects.create_user(username, '', '')
# внесение в группу номер 2, т.е. 'user'
    user.groups.add(2)


  Таблица User, содержит в себе ссылку на таблицу Group, через встроенную 'подтаблицу'
groups.
  Главное корректно заполнить таблицу Group, а далее, добавление прав доступа осуществляется коммандой add('нмер поля записи в таблице Group, соответсвующий определенной группе пользователей')

  Процедура авторизации имеет следующий вид:

def avtorr(user):
# осуществляется проверка принадлежности копределенной группе пользователей
    return True if user.groups.filter(name='user') else False


  Далее, в тексте программы, вставляется проверка, Она вставляется в начале процедуры, которая обрабатывает html страницы, в которых разграничены права доступа.

if autor(request.user)==False:
    return HttpResponseRedirect(reverse("имя процедуры, обрабатывающей случай когда нет прав доступа к данной странице"))


четверг, 14 апреля 2011 г.

Выбор даты в Django




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

year = datetime.date.today().year

class MyForms(forms.Form):
    dataget = forms.DateField(label='Дата:', initial=datetime.date.today,
                                           input_formats=('%d-%m-%Y',),
                                           widget=SelectDateWidget(input_format='%d-%B-%Y',
                                           years=range(year, year-101, -1)))


initial=datetime.date.today - инициализируем форму с текущей датой

input_formats=('%d-%m-%Y',) - отображения даты в виде день, месяц, год

input_format='%d-%B-%Y' - тображение и обработка даты в виджете

%B - месяц словами, в данном случае английские названия

years=range(year, year-101, -1) - задание диапазона лет, чтобы нельзя бало выбрать дату рождения 1104 от Р. Х.)


Во всех полях данной формы, можно отображать произвольную информацию, с помощью модуля: django.utils.dates. Отдуда импортируются словари MONTHS и MONTHS_3.

Их можно переделать следующим образом:

MONTHS = {
1: 'Январь', 2: 'Февраль', 3: 'Март', 4: 'Апрель', 5: 'Май', 6: 'Июнь',
7: 'Июль', 8: 'Август', 9: 'Сентябрь', 10: 'Октябрь', 11: 'Ноябрь',
12: 'Декабрь'
}


Но лучше использовать для этого конвертацию в другие языки названий месяцев).
Для это го надо в settings.py изменить язик:

LANGUAGE_CODE = 'ru-RU'
Время тоже лучше поменять на свой часовой пояс:

TIME_ZONE = 'Europe/Moscow'

Далее использовать стандартный джанговский модуль в forms.py:

from django.forms.extras.widgets import SelectDateWidget

year = datetime.date.today().year

class MyForms(forms.Form):
    dataget = forms.DateField(label='Дата выдачи:',       widget=SelectDateWidget(years=range(year, year-101, -1)), required=False)

required=False - испоьзуется для необязательных для заполнения полей.

Поле ContentTypeRestrictedFileField


Очень полезным полем для загрузки изображений является ContentTypeRestrictedFileField. Удобство его в том, что оно позволяет задать размер загружаемого изображения и, тем самым, обезопасить свой сайт от намеренной загрузки огромных изображений)).

Так же, это поле может использоваться для загрузки файлов.
Ниже приведена форма (forms.py):

class VvForm(forms.Form):
    imgname = forms.CharField(max_length=40, label='Название изображения',
    error_messages={'required': 'Заполните поле'})
    img = ContentTypeRestrictedFileField(label='Изображение',
             content_types='image/x-ms-bmp;image/png;image/bmp;image/jpg;image/jpeg;image/gif',
             max_upload_size=1073741824,
             error_messages={'required': 'Заполните поле'})

content_types='image/x-ms-bmp;image/png;image/bmp;image/jpg;image/jpeg;image/gif' - определяет диапазон возможных загружаемых типов изображений.

max_upload_size=1073741824  - непосредственно, поля для задания размера загружаемого файла.

error_messages={'required': 'Заполните поле') - если поле не заполнено и попытаться осуществить загрузку, то выдаст сообщение:  'Заполните поле'.)

Так же, ознакомиться с функционированием пол, можно здесь: http://djangosnippets.org/snippets/2206/

Каталог блогов

понедельник, 11 апреля 2011 г.

Загрузка текстового файла с помошью динамического upload_to



Итак приступим).

Здесь я опушу как создавал модели и как просто (на мой взгляд) задавать динамический путь для upload_to (использовалась БД PostgreSQL).
Для начала, опишем какие модели использовались

 models.py:

class User(models.Model):
publication_date = models.DateField(auto_now_add=True)
.......
nick = models.CharField(max_length=50)
#auto_now_add=True - автоматически сохраняет текущую дату в поле publication_date, при записи в #БД.

#Следующая модель:

class Ident(models.Model):
user = models.ForeignKey('User')
img = models.ForeignKey('Image')

..........
request_file = models.FileField(upload_to=txt_ident_get_upload_to)


models.ForeignKey('User') - используется для создания ключа (один ко многим) к таблице User. Аналогично Image PrimaryKey не используется. Так как, втоматически создается поле id (User.id, Ident.id) по #которому легко можжно однозначно идентифицировать запись.


Функция, создающая динамический путь кфайлу.

def txt_ident_get_upload_to(instance, filename):
nick= instance.user.nick #так определяется текущий юзер, в поле nick таблицы User
tmpnomer = Img.objects.aggregate(models.Max('nomer'))['nomer__max']# http://docs.djangoproject.com/en/1.3/topics/db/aggregation/
return os.path.join('user', nick, 'idn', str( tmpnomer )+".txt") #Возвращаем функции значени пути к файлу и название текстового файла str( tmpnomer )+".txt"


tmpnomer = tmpnomer + 1 if tmpnomer else 1 - можно использовать, еси до этого в таблицу не вносились данные и там ничего еще не записано. У меня в данном случае это не использовалесь

return os.path.join('user', nick, 'idn', str( tmpnomer )+".txt") #Возвращаем функции значени пути к файлу и название текстового файла str( tmpnomer )+".txt"
Также необходимо импортировать библиотеку для работы с директориями и файлами: import os

Теперь модуль views.py.

Cоздадим специальный файл и сохраним его с помощью upload_to

metadata = u"""{0} {1} {2} #Вместо цифр используются значения полей формы, в таком же порядке, Питоновский способ записи данных
Дата подачи заявки: {4}
""".format(tmpdata.sername, tmpdata.name, tmpdata.ssername, pimg.publication_date) #Значения этих поле подставяться вместо цифр. Значение берется из БД



Импортируем библиотеку для создания временных файлов
from django.core.files.uploadedfile import SimpleUploadedFile

upload_file = SimpleUploadedFile(str(tmpnomer), smart_str(metadata), content_type='text/plain')# Cоздаем специфльный файл


Первое значение - название файла
Второе - умная строка, содержимое файла:http://docs.djangoproject.com/en/1.3/ref/models/instances/
Третья -тип содержимого


Подставляем файл в модель при записи:

ident = Ident(user_id=pdata.user_id, request_file=upload_file)
ident.save()


Все), Файл сохранен по динамическому пути.
В функцию def txt_ident_get_upload_to(instance, filename) можно вставлять любые условя для определения пути, по которому файл сохраниться

Начало)

Здрасте).
Я работаю над одним интересным проектом. Разработка ведется на Django. Это мой первый проект и django  я начинал с нуля (как и Python).
Думаю, что информация опубликованная здесь будет многим интересна и, я очень надеюсь, полезна).
Буду опубликовывать новый материал  по мере возможности.