воскресенье, 15 мая 2011 г.

Ставим django под windows xp

   Устанавливаем под Windows XP SP3. Качаем архивом все файлы, необходимые для установки. Тут всё, что нам понадобится. Оставляю на ваше усмотрение лишь mysql (лично я использую базу, входящую в состав пакета «Денвер 3») и выбор текстового редактора (лично я использую Komodo Edit 5).

   Устанавливаем Python (в пакете находиться python-2.5.4.msi, но можно ставить какой угодно, только надо скачать соответствующие файлы для корректной работы). Для установки указываем директорию C:\Python25. Далее – setuptools-0.6c11.win32-py2.5.exe (этот модуль нам необходим для того, чтобы установить все остальные необходимые библиотеки). Устанавливаем MySQL-python-1.2.2.win32-py2.5.exe (библиотека Python для работы с MySQL) и PIL-1.1.6.win32-py2.5.exe (библиотека для работы с изображениями). Заходим в «Пуск» – «Панель администратора» – «Система». На вкладке «Дополнительно» жмем кнопку «Переменные среды». К значению переменной Path дописываем строку: ;c:\Python25;c:\Python25\Scripts (дописываем, но не удаляем то, что там есть, иначе Windows больше не загрузится!). Делаем мы это для того, чтобы можно было к Python скриптам не только из той дирректории, куда мы его установили. Перезагружаем компьютер.

   Теперь можно проверить, всё ли шло правильно до этого момента. Открываем консоль («Пуск» – «Выполнить» – cmd). Вводим комманду python. Вы должны увидеть что-то вроде:

   Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on win32
Type “help”, “copyright”, “credits” or “license” for more information.

   Двигаемся дальше. Извлекаем файлы из архива Django-1.1.1.tar.gz. Внутри лежит папка Django-1.1.1, копируем её на диск C, переименовываем в django. В консоли вводим следующие команды:

1.chdir C:\django
2.python setup.py install

   Тем самым мы установили все необходимые библиотеки в папку Python25. Директорию C:\django можно удалить.

   Заходим опять в переменные среды и к переменной Path дописываем строку: ;c:\Python25\Lib\site-packages\django\bin и перезагружаем компьютер.

   Давайте опять проверим, всё ли верно. Вводим в консоли следующие команды:

1.python
2.import django
3.django.VERSION

   Вы должны увидеть версию Django: (1,1,1, ‘final’, 0).

Нам остаётся только создать тестовое приложение. Я опустил многие теоретические подробности, оставил только самое необходимое, но достаточное, чтобы Вы смогли установить и настроить Django у себя на компьютере.

   Создадим на диске C: папку home – сдесь мы будем размещать наши сайты. В консоли вводим:

1.chdir C:\home
2.django-admin.py startproject mysite

   Тем самым мы создали дирректорию нашего тестового сайта с минимальным набором скриптов (__init__.py, manage.py, settings.py, urls.py). Далее опять пишем в консоли:

1.cd mysite
2.python manage.py runserver

   Мы запустили встроенный сервер Django. Не закрывая консоль, открываем браузер и вводим строку адреса http://127.0.0.1:8000/. Если Вы всё сделали правильно, вы должны попасть на страницу “Welcome to Django”.
Статья, с небольшими доработками, взята отсуда

четверг, 5 мая 2011 г.

Обработка html страниц и взаимодействие с представлениями



   Для работы с html страницей, использовалось представление показанное ниже.
   views.py:

#импорт библиотеки, для поиска в БД по нескольким критериям.
from django.db.models import Q

#представление, использует в качестве дополнительного значение id, аналогично
этому

def picture(request, id):
    subjects=[]

    #берем значения из БД
    user = User.objects.get(id=id)
   data = Data.objects.get( name=id)
   
   #берем типы изображений
   subj = ImgSubj.objects.all()

    for subj in subj:
       if Image.objects.filter(Q(user=id)& Q(tip_foto=subj)):
            subjects +=[subj]


   if request.method == 'POST':
      #тип изображения
      #береться значение нажатой кнопки с name="tip"
      tipimg = request.POST.get('tip')

      #выбираем из БД изображения, определенного типа, и определенного пользователя
      if ImageSubj.objects.filter(subject=tipimg):
           imagesubjects = ImageSubjects.objects.get(subject=tipimg)
           img = Image.objects.filter(Q(tip_foto=imagesubjects)& Q(user=id))
      else:
           img= Image.objects.filter(user=id)

    #создаем словарь с выбранными значениями
    context = {'user': user,
                     'data': data,
                      'subjects': subjects}

   context.update(csrf(request))

   #передаем значения на указанную страницу  
   usersearch = render_to_string('user.html', context)

   #вывод форм и информации на базовую страницу
   return render_to_response('search/base_index.html', {'usersearch': usersearch},  context_instance=RequestContext(request))

  Далее представлен файл user.html:

<form method="post">


{% if data.sername %}-если значение взято из БД, то будет отображаться
<div class="block1"> <div>

  Фамилия: <b>{{data.sername}}</b> - отображение взятых значений из БД
</div>
<div>
  Имя: <b>{{data.name}}</b>
</div>
<div>
  {% if data.ssername %}
  Отчество: <b>{{ data.lastname }}</b>
{% endif %}
</div>
<div>
  {% if data.databorn %}
  Дата рождения: <b>{{ data.databorn }}</b>
{% endif %}
</div>
 
  
<input name="tip" class="large blue awesome" style="width: 220px; margin: 2px 2px;" type="submit" value="Кнопка"> - отображение кнопки

  {% for subj in subjects %} - цикл для отображения кноаок, соответствующих типам изображений

<input name="tip" class="large blue awesome" style="width: 220px; margin: 2px 2px; "   type="submit"      value="{{ subj }}">

{% endfor %}
   
}

</form>

пятница, 29 апреля 2011 г.

Вывод изображений на страницу


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

views.py:

#берем все изображения, закаченные текущим пользователем
puser = User.objects.get(name=request.user)
images = Image.objects.filter(namer=puser.id)

#необходимо для корректного отображения, чтобы не возникало csrf-ошибки
context = {'images': images}
context.update(csrf(request))
#возвращаем значение со страницей и картинками
return render_to_response('reg_inf/base_index.html', context)


   Далее, в html -коде, пишем:

<form method="post">

{% csrf_token %}

<body>

<table class="t_img">
   {% for img in images %}
      {% if forloop.counter0|divisibleby:"3" %}
      <tr width=151>
      {% endif %}
            <td align="char">
                      <img id="img-{{ img.nomer }}" src='{{ img.mini.url }}' />         
</td>
      {% if forloop.counter|divisibleby:"3" %}
      </tr>
      {% endif %}
{% endfor %}
</table>

</body>
</form>

    {% if forloop.counter0|divisibleby:"3" %} - используется для вывода по три картинки(миниатюры) в строку

вторник, 26 апреля 2011 г.

Отображение файла журнала в джанговской Админке


   В предыдущей статье было описано как реализовать журнал действий пользователь. Здесь будет рассмотрено как просмотреть журнал в админке.

   Для начала, сама процедура отображения содержимого файла.
views.py:

def log(request, userid):
    #по идентификатору выбираем строку из БД с данными о текущем пользователе
    user = LogUser.objects.get(id=userid)
    username = user.name
    #указываем путь к фалу лога пользователя
    url = settings.LOG_FILE_PATH.format(user=username) #MEDIA_ROOT+log.log'
    #считываем информацию из файла
    f = open(url, 'r')
    log = f.readlines()
    #создаем переменную лога для передачи на html страницу
    context = {'log_lines': log}
    return render_to_response('reg_inf/user_log.html', context)

После подключения админки (расскобить две строки в урлах:)), в файле models.py, пишем:

from django.contrib import admin
#импортируем Стандартную джанговскую модель User
#как с ней работать написано здесь 
from django.contrib.auth.models import User
#модель, для отображения имени юзера и поля лога
from reg_inf.models import LogUser

from django.contrib.auth.admin import UserAdmin

#импортируем процедуру из views.py
from reg_inf.views import log

admin.autodiscover()

#процедура, для отображения ссылки в админке на файл лога
def user_view_log_link(user):
    #id юзека, для определения имени в БД
    p = user.id
    #возвращаем ссылку, при нажатии на которую, вызывается процедура log
    #ей передается id юзера, на против которого была нажата ссылка
    return '<a href="%s">:Журнал</a>' % reverse(log, args=[p])

#создаем дополнительное поле для ссылки
user_view_log_link.allow_tags = True

#создаем класс, для отображения в админке
class MyUser(admin.ModelAdmin):
  list_display = ('name', user_view_log_link,)
#регистрируем модель LogUser как потомка MyUser
admin.site.register(LogUser, MyUser)

Для корректной передачи id юзера, необходимо записать в url.py:

urlpatterns = patterns('reg_inf.views',
    (r'^log/(?P<userid>\d+)$', 'log'),


   Конешно можно было отобразить ссылку на файл прямо в стандартной модели User. Для этого её необходимо выгрузить из джанго и щзарегать снова. Но как показывает опыт, при таком отображении локально все работает отлично, при закгрузке на сервер под Апачем, а именно, ссылка то проподает, то появляется снова, то админка не грузиться.

среда, 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).
Думаю, что информация опубликованная здесь будет многим интересна и, я очень надеюсь, полезна).
Буду опубликовывать новый материал  по мере возможности.