Развел небольшой холивар на своем любимом блоге.
-
13Sep[?]
-
07Aug
Хоть и старенькое, но полезненькое.
Основатель Pinax James Tauber. Рассказывает о своем детище. Pinax – это сборная солянка джанго апов для ускорения разработки. Апы в основном с уклоном на социальность. Вобщем упомянутые апы в любом случае стоят вашего внимания.PyCon 2009
[?]Tags: djangoconf, pinax, pycon, Python, video
-
01Aug
Lazy Crazy Coder’s blog from Alexander Artemenko.
Для себя отметил пару ссылок оттуда.
Big list of Django tips (and some python tips too) – статья не новая, но есть еще очень актуальные вещи.
[?] -
01Aug
с утра зашел проверить утренние филы. И вот наткнулся celery. Теперь тяжеловесные задачи на откладывать на потом. И делается это очень просто, по крайне мене судя по документации. Тут более подроная апишка.
Оставил себе таск на выходные порытся и тут. Обо всем напишу тут.
PS: первое, к чему бы я сразу это прикрутил – это отсылка мыла. Ее всегда полезно отложить
Всем удачных выходных.
[?]Tags: celery, django, optimizations, Python, RabbitMQ, tasks, threads, ZeroMQ
-
31Jul
Задача. У вас есть две таблици, связаны друг с другом как OneToOne. Но в админке их не удобно править раздельно. Хочется это делать в одном месте. К примеру возьмем профайл и юзер. Хотя мне кажется, что профайлы в джанго — это как кость в горле. Из-за них объединение присоединение больших приложений типа формов или блогов превращается в целый геморой. Но свои соображения и идеи по этому поводу я освещу в отдельно статье.1. Вывод записей. Решается просто вы добавляете в админ-моделе ( не знаю, как правильно назвать этот элемент джанги, ваш наследник от admin.ModelAdmin ) функцию
-
def user_name(self,obj):
-
user = obj.user
-
return u'%s %s' %(user.first_name,user.last_name)
-
user_name.short_description = u'Имя'
и в list_display строку с именем этой функции
2. Поиск. Тут все просто. В search_fields добавляем user__username
3. Фильтры. Возможно вы мне подскажите, но у меня не получилось добавить поле из связной таблици в качестве фильтра. Поэтому я просто использую в админке как «основную» – ту таблицу, в которой поля будут использоваться в качестве фильтров. Надо будет залезть в исходники с грязными ногами и выяснить, что за лажа.4. Редактирование. Создаем отдельно форму и добавляем в ней новые поля, и переопределяем инициализацию и сохранение.
-
class ProfileForm(forms.ModelForm):
-
first_name = forms.CharField(max_length=30,label=u'Имя')
-
last_name = forms.CharField(max_length=30,label=u'Фамилия')
-
-
def __init__(self,*args,**kwargs):
-
super(ProfileForm,self).__init__(*args,**kwargs)
-
user = pr.user
-
self.initial.update({
-
'first_name':user.first_name,
-
'last_name':user.last_name
-
})
-
-
def save(self,*args,**kwargs):
-
user = self.instance.user
-
user.first_name = self.cleaned_data['first_name']
-
user.last_name = self.cleaned_data['last_name']
-
user.save()
-
return super(ProfileForm,self).save(*args,**kwargs)
-
-
class Meta:
-
model = M.StatusChatProfile
Форму передаем нашей админ-моделе.
С формой есть маленькая проблемка, на которую я наступил. В момент, когда вызывается super(…).save(…) фактическое сохрание данных еще не происходит. И это необходимо учитывать, в случае, если его “таблица напарник” при сохранении изменяет в нем же какие либо поля. Данные в этом случае перетрутся.Спасибо за внимание. Вам успехов и удачного дня.
[?] -
-
29Jul
только что наткнулся на этот “АП”, хотя на самом деле – это такой сборничек маленьких полезных функций и пары декораторов. В принфипе ничего сверхестественного. Но смотреть всем обязательно.
[?] -
24Jun
Пока мой ноут еще жив, а читатели делают ставки, я решил перед сном еще расковырять django-debug-tolbar.
По сути все панели построены на хаках. Т.е. В архитектуре самого движка не закладывалась такая фишка. Т.е. К примеру берут класс BaseCache для из модуля django.core.cache.backends.base делают на его основе наследника, который делает тоже самое, только еще и считает. И заменяют полученный класс в модуле. Т.е. теперь там лежит «тулбарный» класс, и джанго для своей кухни будет брать его, а он уже будет делать свои «темные делишки».
Я для своего csvlog выкавырял оттуда только sql. Теперь я могу еще и вести лог всех запросов, проходящих в вашем апе, и говорить, сколько времени они съели. Сделал сразу компонентную структуру, почти как у этого самого тулбара, так что если что можете отключать.
А хак этот выглядит совсем не сложно:
-
from django.db.backends import util
-
import time
-
from csvlog.middleware import glog
-
class DatabaseStatTracker(util.CursorDebugWrapper):
-
def execute(self, sql, params=()):
-
start = time.time()
-
try:
-
return self.cursor.execute(sql, params)
-
finally:
-
stop = time.time()
-
glog.dbg(['__SQL__',stop-start,sql,unicode(params)])
-
util.CursorDebugWrapper = DatabaseStatTracker
Да, и я не тестил, но очень сильно подозреваю, что теперь кто-то из них двоих не сможет считать сюелины, и скорее всего тот, чей ап идет позже в INSTALLED_APPS.
PS: Забыл предварительно проверить свободное место на винте. Бедняга должен умереть свободным.
[?]Tags: django, django-csvlog, django-debug-tolbar, hack, Python
-
-
22Jun
Исправил много мелких багов, но надо уже написать нормальную доку. Есть еще идея, взять кусочки из джанго тулбара и к примеру дать возможность выводить все СЮЛ запросы.
Кроме того, сейчас пишу еще одно приложения – простое для принятия платежей. Хотя, получилась довольно универсальная фишка. Так вот в нем я использую эти логи, но есть вероятность, хотя и маленькая, но есть, что комуто логи эти будут не подуше, поетому я еще и заглушку сделал. Такие заглушки можно писать для взаимодейстивя между джанго приложений.
В папку с аппом добовляем файлик extapp.py
-
__all__ = ['glog']
-
from django.conf import settings
-
if 'csvlog' in settings.INSTALLED_APPS:
-
from csvlog import glog
-
else:
-
class glog():
-
@staticmethod
-
def get_log_func(self,*args):
-
return lambda *args:None
-
for n in ['err','imp','inf','log','trc','dbg']:
-
setattr(glog,n,staticmethod(lambda *args:None))
проверяет есть ли апп, если нет, то пишем для него заглушку. А везде в коде просто юзаем
-
from extapp import glog
I love Python!
[?]Tags: app, csv, django, django-csvlog
-
-
17Jun
Когда делая выборку из объекта родителя и хочется получать объекты наследники, то я использую такой финт
-
from django.db import models
-
-
class MBase(models.Model):
-
field1 = models.CharField(max_length=10)
-
field2 = models.CharField(max_length=10)
-
classname = models.CharField(max_length=10)
-
def save(self,*args,**kwargs):
-
self.classname = self.__class__.__name__.lower()
-
super(MBase,self).save(*args,**kwargs)
-
@property
-
def rel_obj(self):
-
return getattr(self, self.classname)
-
-
class MFirst(MBase):
-
myf1 = models.CharField(max_length=10)
-
-
class MSecond(MBase):
-
myf2 = models.CharField(max_length=10)
А в коде выходит примерно следующее
-
In [11]: M.MBase.objects.get(id=3)
-
Out[11]: <MBase: MBase object>
-
-
In [12]: M.MBase.objects.get(id=3).rel_obj
-
Out[12]: <MFirst: MFirst object>
-
-
In [13]: M.MBase.objects.get(id=3).rel_obj.myf1
-
Out[13]: u'Hi1'
PS: Чтоб не мучаться, можно вынести функционал в абстрактную модель.
-
class RelatedBase(models.Model):
-
childclassname = models.CharField(max_length=20,editable=False)
-
def save(self,*args,**kwargs):
-
if not self.childclassname:
-
self.childclassname = self.__class__.__name__.lower()
-
super(RelatedBase,self).save(*args,**kwargs)
-
@property
-
def rel_obj(self):
-
return getattr(self, self.childclassname)
-
class Meta:
-
abstract=True
а все базовые классы уже будут от нее наследоваться
[?] -
-
07Jun

Хоть выкраить лишнюю минутку было более чем сложно. Последние две недели у меня Django-NonStop.Все основаное на идее, которую я описывал ранее.
Вот, вчера ночью таки закончил. На самом деле я это штуку реализовал уже давно, просто захотелось упаковать в более продажный вид, ну и по случаю добавил там рюшечек всяких прикольных
В репозитарии лежит пример использования этого приложения вместе с апом. Так что можете просто открыть settings.py и глянуть, какие поля в настройках необходимо добавить. Не стандартные поля помечены ##ADD
Что под капотом?
Возможность логить. (В шоке?)
-
from django.http import HttpResponse
-
from csvlog import glog
-
def somelog(request):
-
glog('executin log by default name')
-
glog.err('ERR, some error hapend')
-
glog.imp('IMP, some important information')
-
glog.inf('INF, some information')
-
glog.log('LOG, some log')
-
glog.trc('TRC, some trace')
-
glog.dbg('DBG, debug information')
-
return HttpResponse('OK')
И вы можете сами указывать какие данные из стека вы хотели бы сторить. Настройка представляет собой набор ссылок на функции.
Автоматом сторятся данные реквеста и респонса. Точна также вы можете задавать какие куски этих объектов идут к вам в лог.Также под ваш лог, автомат создаётся объект в моделях csvlog.models.LogDump. И вы можете импортировать в него данные из логов и работать с ними через вашу ORM. Пожалуй это основной плюс.
-
python manage.py log_to_base log.csv
Ну и маленькая рюшечка в нагрузку. Баг репортинг.
Все несловленные вами эксепшены, ловятся ей, и сторятся в базу. Я когда узнал, сколько всего можно то от ексепшена то узнать, я не был уверен, что мне базы то хватит. А пользователю выводится предложение еще и обматерить вас, ну т.е. оставить свой баг репорт.
Проект очень, очень нуждается в жесткой критике.
[?] -





Recent Comments