• 16Apr

    elite-board Давно хотел переделать сайт своего отца, выдалась свободная минутка и… Это первый мой Django проект, увидевший мир.www.elite-board.net.ua доска объявлений. Ну и пока неделя работы, полет нормальный. Единственное, дизайн, рисовать я не умею, так что особо не стебайтесь, но критику в любом случае выслушать готов.

    Что внутри:

    • I18N — но этим уже никого не напугаешь
    • openid авторизация — почти самописная. Это помимо базовой.

    • Поиск — django-sphinx.
    • Вложеная навигация по тегам.
    • Автодогрузка объявлений при переходе в конец страницы.
    • предпросмотр заотаченых к объявлению картинок

    • Ну и контроль ошибок и CSV логи. Если на сайте происходит сбой, пользователю предлагают самому дополнить информацию о том, как он её получил.

    Хочу услышать вашу критику.

    Share and Enjoy:
    • Facebook
    • LinkedIn
    • del.icio.us
    • StumbleUpon
    • MySpace
    • Reddit
    • Digg
    • Google Bookmarks
    • Technorati
    • email
    • Print
    • Sphinn
    • Mixx
    • Blogplay
    • Add to favorites
    • Linkter
    • Live
    • MSN Reporter
    • NewsVine
    • RSS
    • Yahoo! Bookmarks
    • Yahoo! Buzz
    • Yigg
    Rating 3.00 out of 5
    [?]

    Tags: , , ,

  • 12Dec

    Наверно, не очень хорошо, менять часто дизайн своего блога, но просто заметил, что в Iceweasel у меня дизайн налазит.

    Кстате, наконецто решился и перешел полностью в линух на дестопной тачке. До этого у меня весела винда, на ней вмварка, в вмварке дебиан, самба сервер расшаривал папки для работы, в винде подключал сетевой диск и работал как лакально (…. в сундуке яйцо, в яйце игла … ).  Винда согнулась, я понял, что от нее мне особо для работы ничего не надо. И теперь у меня вот только Дебиан.

    Ну вообщето не совсем “только”. Винда осталась, второй системой поставил, вопервых мне нужен флеш, а во вторых я раз в месяц шпилю в Героев 5. Но чтото мне подсказывает, что скоро и она займет свое место в вмварке )

    Share and Enjoy:
    • Facebook
    • LinkedIn
    • del.icio.us
    • StumbleUpon
    • MySpace
    • Reddit
    • Digg
    • Google Bookmarks
    • Technorati
    • email
    • Print
    • Sphinn
    • Mixx
    • Blogplay
    • Add to favorites
    • Linkter
    • Live
    • MSN Reporter
    • NewsVine
    • RSS
    • Yahoo! Bookmarks
    • Yahoo! Buzz
    • Yigg
    Rating 3.00 out of 5
    [?]

    Tags: , ,

  • 03Dec

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

    теперь если функция cp_before возвратит значение – это значит это и будет результатом всего запроса. Появилась функция cp_after которая вызывается в конце всей обработки

    результат работы функций cp__* может быть не обязательно наследник HttpResponse, но и любая другая структура языка, которая уже будет преобразована к оному с помощью функции cp_prepare

    Вот собственно необходимые доработки в классе AddNewUrl :

    1.      def __call__(self,*t,**k):
    2.         if 'before' in self.prefix :
    3.             ret = self.prefix['before'](*t,**k)
    4.             if ret:
    5.                 return ret
    6.         ret =  self.view(*t,**k)
    7.         if 'prepare' in self.prefix:
    8.             newret =   self.prefix['prepare'](ret,*t,**k)
    9.             if newret: ret = newret
    10.         if 'after' in self.prefix:
    11.             self.prefix['after'](*t,**k)
    12.         return ret

    теперь, к примеру задача вывода JSON структуры сводится к

    1. from django.http import HttpResponse
    2. import simplejson as json
    3. class BaseViews(object):
    4.     def prepare_cp(self,response,request):
    5.         return HttpResponse(json.dumps(response))
    6.     def cp__all_rooms(self,request):
    7.         return {'hi':'World','id':request.GET.get('id')}
    Share and Enjoy:
    • Facebook
    • LinkedIn
    • del.icio.us
    • StumbleUpon
    • MySpace
    • Reddit
    • Digg
    • Google Bookmarks
    • Technorati
    • email
    • Print
    • Sphinn
    • Mixx
    • Blogplay
    • Add to favorites
    • Linkter
    • Live
    • MSN Reporter
    • NewsVine
    • RSS
    • Yahoo! Bookmarks
    • Yahoo! Buzz
    • Yigg
    Rating 3.00 out of 5
    [?]

    Tags: , , , , ,

  • 01Dec

    Сегодня из интереса написал небольшой модуль сериализации в ХМЛ. На скорую руку. Как по мне – довольно элегантное решение. Как думаете?

    1. def xml_escape(text):
    2.     return str(text).replace('&','&amp;').replace('<','&lt;').replace('>','&gt;').replace('"','&quot;').replace("'",'&apos;')
    3.  
    4. def xmlSerial(name,attr=None,inner=None):
    5.     if attr:
    6.         name_attr = name+' '+' '.join(map(lambda (a,b):a+'="'+xml_escape(b)+'"',attr.items()))+' '
    7.     else:
    8.         name_attr = name
    9.    
    10.     if inner:
    11.         if type(inner) == list:
    12.             inner_str = ''.join(map(lambda a: xmlSerial(*a),inner))
    13.         else:
    14.             inner_str = inner
    15.         return '<'+name_attr+'>'+inner_str+'</'+name+'>'
    16.     else:
    17.         return '<'+name_attr+'/>'

    Вот, как его мона юзать:

    1. print xmlSerial('HI',{'a':'1','c':3,'d':'WOW'},[['RR'],['WOW',{'and_attr':'45t'}],['WIN',{'a':1},'HI IT IS INNER']])
    2. print xmlSerial('HI',{'a':'1','c':3,'d':'WOW'},[['RR'],['WOW',{'and_attr':'45t'}]])
    3. print xmlSerial('HI',{'a':'1','c':3,'d':'WOW'},[['RR'],['WOW']])
    4. print xmlSerial('HI',{'a':'1','c':3,'d':'WOW'},'AND INNER')
    5. print xmlSerial('HI',{'a':'1','c':3,'d':'WOW'})
    6. print xmlSerial('HI',{'a':'1'})
    7. print xmlSerial('HI')
    Share and Enjoy:
    • Facebook
    • LinkedIn
    • del.icio.us
    • StumbleUpon
    • MySpace
    • Reddit
    • Digg
    • Google Bookmarks
    • Technorati
    • email
    • Print
    • Sphinn
    • Mixx
    • Blogplay
    • Add to favorites
    • Linkter
    • Live
    • MSN Reporter
    • NewsVine
    • RSS
    • Yahoo! Bookmarks
    • Yahoo! Buzz
    • Yigg
    Rating 3.00 out of 5
    [?]

    Tags: , , , ,

  • 21Nov

    По сути мы к урлам привязываем функции, а значит получается мы используем простое функциональное программирование, и не очевидно, как в такой ситуации воспользоваться всем обилием объектно-ориентированого программирования, которое предоставляет Python.

    Также, Django, продвигает полезную фикчу, которое должно подтолкнуть пользователей всего мира делится своим джанговским кордом, это инклюд одного приложения в другого. И все было бы очень просто и радужно, если б не несколько небольших «но». Это «MIDDLEWARE_CLASSES». Как правило, приложениям, которые вы хотите подключить, необходимо с собой тянуть эти классы. Тем, кто не в курсе, объясню, в них собран функционал, который будет запускатся до и после вызова функции, которая закрепленная за урлом. Но иногда этот функционал необходим только этому апликейшену, а для остальных это просто лишний и не нужный своп. Нет возможности привязать миддл только к определенному апликейшену.

    Вопросы расширяемости. Это вопрос объектно-орентированого программирования, о котором я говорил выше. Его по сути нет. Вам дали апликейшен – пользуйтесь. Все, что можно менять в его работе – лежит в настройках ВСЕГО проекта, либо в параметрах передаваемых самому инклюду. А хотите больше? Копайтесь в моих исходниках и пишите то, что вам надо.

    Вот мое решение.

    1.  
    2. from django.conf.urls.defaults import url
    3.  
    4. class AddNewUrl(object):
    5.     def __init__(self,prefix,view,*t):
    6.         self.prefix = prefix
    7.         self.view = view
    8.         self.t = t
    9.     def __call__(self,*t,**k):
    10.         if 'before' in self.prefix :
    11.             self.prefix['before'](*t,**k)
    12.         return self.view(*t,**k)
    13.  
    14. def newpatterns(prefix, *args):
    15.     pattern_list = []
    16.     for t in args:
    17.         pattern_list.append(newurl(prefix, *t))
    18.     return pattern_list
    19.  
    20. def newurl(prefix,regex,view,*t):
    21.     return url(regex,AddNewUrl(prefix,view,*t),*t)
    22.  
    23.  
    24. def classpatterns(cp):
    25.     o_cp = cp()
    26.     cp_prefix = {}
    27.     if hasattr(o_cp,'before_cp'):
    28.         before_cp = getattr(o_cp,'before_cp')
    29.         if callable(before_cp):
    30.             cp_prefix['before'] = before_cp
    31.     func_list = ()
    32.     for item in dir(o_cp):
    33.         if item.startswith('cp__'):
    34.             item_func = getattr(o_cp,item)
    35.             if callable(item_func):
    36.                 func_list = func_list + ((r'^'+item[4:]+'/$',item_func),)
    37.     #raise str(func_list)
    38.     return newpatterns(cp_prefix,*func_list)

    Теперь урлы и вьювы – объединены в одном классе.
    Если вы хотите написать обработчик урла «^home/$» , то вам можно просто написать функцию cp_home в которой и будет вестись обработка вашего запроса.

    Если у вас есть функция, которую необходимо дергать перед запускам каждого обработчика, то назовите ее before_cp

    Но есть и ограничения, которые я еще не преодолевал, т.к. они пока особо меня не касались:

    Нельзя в полной мере воспользоваться регекспами в урлах.
    Нельзя использовать инклюды внутри такого аппликейшена. А вы думаете они правда нужны при таком построении приложения?
    Приложения такого типа типа лучше не использовать на «первом уровне» а только инклюдить в основное.

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

    Вот пример использования:

    файл ajax/vurl.py

    1.  
    2. from newpatern.defaults import newpatterns, classpatterns
    3. django.http import HttpResponse
    4. class Views(BaseViews):
    5.     def cp__connect(self,request):
    6.           return HttpResponse('HI ALL')
    7.     def cp__NO(self,request):
    8.           return HttpResponse(reqest.GET.get('n'))
    9.  
    10. urlpatterns = classpatterns(Views)

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

    В Ваш файл с урлами просто вставте:

    1. (r'^flashajax/',include('ajax.vurls')),

    Теперь по запросу flashajax/connect/
    в ответ получить “HI ALL”

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

    Что касается меня, то я его уже юзаю в одном из своих проектов, пока успешно. Хотя проект еще не в продакшене, поэтому однозначно судить нельзя

    Share and Enjoy:
    • Facebook
    • LinkedIn
    • del.icio.us
    • StumbleUpon
    • MySpace
    • Reddit
    • Digg
    • Google Bookmarks
    • Technorati
    • email
    • Print
    • Sphinn
    • Mixx
    • Blogplay
    • Add to favorites
    • Linkter
    • Live
    • MSN Reporter
    • NewsVine
    • RSS
    • Yahoo! Bookmarks
    • Yahoo! Buzz
    • Yigg
    Rating 4.00 out of 5
    [?]

    Tags: , , , ,

   

Recent Posts

Recent Comments

  • Я просто оставлю это тут: ...
  • спасибо...
  • Если вдуматься в каждое слово, то время беСконечно в русском...
  • Спасибо, Евгений, исправленно.P.S.: перехал на диску...
  • за опечатку - спасибо...