request.path # the full path, not including the domain "/hello/" but including the leading slash
request.get_host() # the host (i.e., the “domain,” in common "127.0.0.1:8000" or parlance) "www.example.com"
request.get_full_path() # the path, plus a query string (if available) "/hello/?print=true"
request.is_secure() # True if the request was made via HTTPS; True or False otherwise, False
Jun 30, 2011
Request useful methods
Jun 29, 2011
Find the real location of the exception
The problem with Django is that there are certain circumstances where it will hide the actual error message and traceback and replace it will a higher level exception, but with the traceback then being where that higher level exception was raised. This is one such case. To try and find the real location of the exception add the following to your WSGI script file.
import traceback
import sys
def dump_exception(callable):
def wrapper(*args, **kwargs):
try:
return callable(*args, **kwargs)
except:
traceback.print_exception(*sys.exc_info())
return wrapper
import django.core.urlresolvers
urlresolvers.get_callable = dump_exception(urlresolvers.get_callable)
This wraps the call which is doing the lookup and will dump out the error message it raises before the traceback gets thrown away.
Hg or git branch in bash prompt
in ~/.bashrc (Ubuntu 12.04)
hg_branch() {
hg branch 2> /dev/null | \
awk -v "clrp=$txtpur" -v "clrr=$txtrst" \
'{ print clrp "@hg:" $1 clrr}'
}
hg_dirty() {
[ $(hg status 2> /dev/null | wc -l) != 0 ] && \
echo -e "${txtred}*${txtrst}"
}
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\W$(hg_branch)$(hg_dirty)\$ '
fi
then your prompt will looks like:someproject$ vi /home/alexey/.bashrc # make changes above
someproject$ source /home/alexey/.bashrc
someproject@hg:liveserver$ # liveserver is current brunch
someproject@hg:liveserver$ hg branch
liveserver
someproject@hg:liveserver$ touch blabla
someproject@hg:liveserver*$ # asterisk indicates that VCS has changes
someproject@hg:liveserver*$ hg st
? blabla
Also you can do the same for git:
git_branch() {
git branch --no-color 2> /dev/null | grep "*" |\
awk -v "clrp=$txtpur" -v "clrr=$txtrst" \
'{ print clrp "@git:" $2 clrr}'
}
git_dirty() {
[ $(git status --short 2> /dev/null | wc -l) != 0 ] && \
echo -e "${txtred}*${txtrst}"
}
Labels:
bash,
bash prompt,
git,
mercurial
Jun 25, 2011
Изменение названия модуля в django admin
class Stuff(models.Model):
class Meta:
verbose_name = u'The stuff'
verbose_name_plural = u'The bunch of stuff'
django admin использует app_label.title() поэтому мы можем использовать небольшой хак: подкласс str с переопределенным методом title:
class string_with_title(str):
def __new__(cls, value, title):
instance = str.__new__(cls, value)
instance._title = title
return instance
def title(self):
return self._title
и в итоге получаем:
class Stuff(models.Model):
class Meta:
app_label = string_with_title("stuffapp", "The stuff box")
# 'stuffapp' is the name of the django app
verbose_name = 'The stuff'
verbose_name_plural = 'The bunch of stuff'
См. также: Rename django admin app name and breadcrumbs
Jun 24, 2011
Полезные функции в Django
В Django существует куча полезных функций и классов, которые помогают выполнять простые и полезные действия раз от разу. Предлогаю Вам свое видение этого списка:
- django.utils.datastructures.SortedDict
- django.utils.datastructures.MultiValueDict
- По умолчанию в Python объект
dict
не поддерживает сортировку ключей и несколько значений для одного ключа. Именно поддержку этих возможностей дают перечисленные выше классы. Например, поддержкаGET
,POST
,REQUEST
массивов в объектеrequest
реализована в видеMultiValueDict
объектов. - django.utils.dates
- Этот модуль содержит разнообразные массивы, которые используются для печати SelectDateWidget'а.
- django.utils.encoding.force_unicode
- Переводит любой Python объект в
unicode
. Так же переводит вunicode
любую модель Django у которой есть метод__unicode__
. - django.utils.html.clean_html
- Очищает переданный в функцию HTML строку, а именно:
- Конвертирует
<b>
и<i>
в<strong>
и<em>
. - Правильно кодирует все амперсанды.
- Удаляет все
"target"
аттрибуты с тегов<a>
. - Конвертирует явно заданные баллетсы (bullets) в неупорядоченные HTML списки.
- Удаляет из текста фрагменты
"<p> </p>"
, но только если они находятся в конце текста.
- Конвертирует
- django.utils.html.urlize
- Переводит все ссылки в тексте в
<a>
тэги. - django.utils.safestring.mark_safe
- Обозначает любой строковой объект, как безопасный для того, чтобы он мог был беспрепятственно распечатан в шаблоне без эскейпинга символов.
- django.utils.text.get_text_list
- Для описания работы этой функции и
doctest
'а хватит: - >>> get_text_list(['a', 'b', 'c', 'd'])
- u'a, b, c or d'
- >>> get_text_list(['a', 'b', 'c'], 'and')
- u'a, b and c'
- >>> get_text_list(['a', 'b'], 'and')
- u'a and b'
- >>> get_text_list(['a'])
- u'a'
- >>> get_text_list([])
- u''
Labels:
django
Jun 22, 2011
Dkim
pydkim
Python module that implements DKIM (DomainKeys Identified Mail) email signing and verification. It also provides helper scripts for command line signing and verification.Snippet
from django.core.mail.backends.smtp import EmailBackend
from django.conf import settings
import dkim # http://hewgill.com/pydkim
class DKIMBackend(EmailBackend):
def _send(self, email_message):
"""A helper method that does the actual sending + DKIM signing."""
if not email_message.recipients():
return False
try:
message_string = email_message.message().as_string()
signature = dkim.sign(message_string,
settings.DKIM_SELECTOR,
settings.DKIM_DOMAIN,
settings.DKIM_PRIVATE_KEY)
self.connection.sendmail(email_message.from_email,
email_message.recipients(),
signature+message_string)
except:
if not self.fail_silently:
raise
return False
return True
Изменение размеров всех фото в папке
#!/bin/bash
for f in *.JPG
do
NEWNAME=`basename ${f} .JPG`_OK.jpg
echo $NEWNAME
convert -resize '1024!x768' $f $NEWNAME
done
Jun 20, 2011
Fast Flex app compilation
/p/projects/networkingtv/flex_sdk/bin/fcsh
(fcsh) mxmlc -load-config+=flex-config.xml
Labels:
flex
Media
Videos
ffmpeg -i input.mpg -ar 22050 -ab 64 -f flv -s 320x240 -r 29.970 -b 1000k -y output.flv
-ar -- is the Audio sample rate ie, 11050, 22050, 44144, and 48000
-ab -- is the Audio Bitrate ie, 64Kbits, 128Kbits, 384Kbtis, etc.
-r ---- is the Frame Rate or fps of the finished video, ie 24, 25, 29.970 etc.
-b ---- is the Bitrate you want to set the flv video to ie, 360k, 1000k etc.
# better
mencoder input.mpeg -ovc lavc -lavcopts vcodec=mpeg4:mbd=2:trell -oac copy -vf scale=360:240 -o output.avi
# worse
ffmpeg -i input.avi -b 1000 -s 640x480 -vcodec mpeg4 -r 30000/1001 output.avi
# or
ffmpeg -i M2U00009.MPG -ar 44100 -ab 128k -s 720:480 -padtop 46 -padbottom 50 -padcolor 000000 -ss 00:00:40 -t 00:02:55 -f mp4 grok3.avi
# for android
https://help.ubuntu.com/community/AndroidVideoEncoding
Images
convert -resize '320x240!' 002.jpg thmb_002.jpg
Screenshot
sudo apt-get install scrot
scrot
# or
sleep 10 && scrot
# or
scrot -e 'mv $f /your/pictures'
Удаление элементов из списка
a=range(10);
for item in a:
if item < 5:
a.remove(item)
print a
# Вернет [1, 3, 5, 6, 7, 8, 9]
Почему так происходит? Потому что при удалении элемента из списка, индекс не уменьшается. А значит, следующий элемент списка будет пропущен. Отчаявшись, люди идут на такие ухищрения:
i = 0
while i < len(a):
if i < 5:
del a[i]
else:
i += 1
Нам на помощь приходит такая замечательная функция как filter(func, a). Она создает новый список из элементов списка, для которым функция func(item) вернет истину.
filter(lambda x: x <= 5, a)
# Вернет [6, 7, 8, 9]
[i for i in a if i >= 5]
# Также вернет[6, 7, 8, 9], да и выглядит красивее.
print a # Список a остался неизменным
Labels:
core python,
python
Итерация по спискам
for i in range(len(a)):
print "Под номером %d находится элемент %s" % (i, a[i])
Это работает, но что мы сделали лишнего: посчитали длину списка и создали еще один список, с длиной равной длине списка a. Нас немного спасет xrange, но правильнее от этого не станет. Если вам и правда необходимы индексы элементов, используйте enumerate.
for i, item in enumerate(a):
print "Под номером %d находится элемент %s" % (i, item)
enumerate(a) не создает лишних списков, он возвращает поочередно элементы списка в виде (<индекс>, <элемент>). Да и выглядит такая конструкция гораздо понятнее.
Labels:
core python,
python
Encription (len=128)
import hashlib
o = hashlib.sha512("22222@aaa.com" + str(datetime.datetime.now()))
o.hexdigest()
Labels:
core python,
python
MySQL
# dump
mysqldump db_name -uroot -p > ffff.sql
mysql db_name -uroot -p < ffff.sql
# drop all tables
mysql -BNe "show tables" db_name | awk '{print "drop table " $1 ";"}' | mysql db_name
PostgreSQL
#dump
# http://stackoverflow.com/questions/2893954/how-to-pass-in-password-to-pg-dump
pg_dump -U db_user db_name | gzip > dump.sql.gz
gunzip dump.sql.gz
psql -U db_user db_name -f - < dump.sql
#create
#grant usage on *.* to uuuu@localhost identified by 'pppp';
grant all privileges on database DB_NAME to USER_NAME;
#priveleges
sudo vi /etc/postgresql/8.4/main/pg_hba.conf
local all postgres trust
#Show all tables
\dt
# create user
createuser -U postgres -P -S -D -R -e username
# create db
createdb -U postgres -E UTF8 -T template0 -e -O username database_name
Labels:
postgre
Bare git
# на сервере cd ~/ mkdir someproject.git cd someproject.git git init --bare ### old version is ### git init-db # у себя (в директории с сырцами) git remote add hosting ssh://someusername@somedomain.com:2200/home/someproject.git git push hosting master # снова на сервере $ cd ~/ $ git clone ~/someproject.git # создание бранча git checkout -b somebranchname --track hosting/somebranchname
Labels:
deployment,
git
SSH без пароля
Сначала генерируется ключ:
Так же удобно прописать алиасы
ssh-keygen
chmod 644 ~/.ssh/id_rsa.pub
ssh-agent bash
ssh-add
Затем он копируется на сервер:cd ~/.ssh/ && ssh-copy-id -i id_rsa serveruser@host
Так же удобно прописать алиасы
Class-based views
class SomeFormView(TemplateResponseMixin, View):
template_name = 'some_form.html'
def get(self, request):
form = SomeForm()
return self.render_to_response({
'form': form,
})
def post(self, request):
form = SomeForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Your form has been saved!')
return self.render_to_response({
'form': form,
})
class AjaxThingView(View):
# Note that I don't subclass the TemplateResponseMixin here!
def get(self, request):
return HttpResponse(status=404)
def post(self, request):
id = request.POST.get('id')
# Do something with the id
return HttpResponse('some data')
Выполняем тесты быстрее
import sys
if 'test' in sys.argv:
DATABASES['default'] = {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'test_database.sqlite'
}
Перевод разных слов на разных языках в django
from django.utils.translation.trans_real import translation
trans_en = translation('en')
trans_es = translation('es')
print trans_en.ugettext('word')
print trans_es.ugettext('word')
Labels:
django,
translation
Сached decorator for functions
from django.core.cache import cache
from hashlib import sha256
def cached(ctime=3600):
def decr(func):
def wrp(*args,**kargs):
key = sha256(func.func_name+repr(args)+repr(kargs)).hexdigest()
res = cache.get(key)
if res is None:
res = func(*args,**kargs)
cache.set(key,res,ctime)
return res
return wrp
return decr
Создание локальной копии документации Django
Запускаем командую строку и устанавливаем Sphinx:
Внутри вашей директории с Django находим папку docs, заходим в нее и:
Вот и все! Внутри docs выполняем:
sudo easy_install Sphinx
Внутри вашей директории с Django находим папку docs, заходим в нее и:
make html
Вот и все! Внутри docs выполняем:
_build/html/index.html
Watch what SQL queries Dango produces
from django.db import connection
print connection.queries
print connection.queries[-1]['sql']
Or in Django >= 1.3
import logging
l = logging.getLogger('django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())
Using tshark
sudo tshark -Tfields -e mysql.query -i any -R 'mysql.query'
mysql -h 127.0.0.1 -u root -p
Setup django environment in standalone script
from django.core.management import setup_environ
import settings
setup_environ(settings)
Quick and pritty iteration
qs = Item.objects.filter(...).values_list('title', 'amount', 'price')
for title, amount, price in qs:
print title, amount
total += amount * price
Django apps
Templates
django-dbtemplates - templates in databaseCMS
django-dbtemplates - templates in databaseTesting
needle - checks that CSS renders correctly by taking screenshots of portions of a website and comparing them against known good screenshotsTranslation
django-rosetta - .po files (admin interface, suggestions via Google Language)django-nani - simple, predictable and compatible multilingual database contents
Log
django-sentry - real-time logging in admindjango-timelog - performance logging middlware and analysis tools
django-peavy - application for capturing logging to a database
Sql
django-unjoinify - a library for efficiently retrieving deeply-nested data setsdjango-queryset-transform - experimental method for QuerySets, for clever lazily evaluated optimisations
django-qmixin - app for extending managers and the querysets they produce
Social
django-twitter-users - sign in with TwitterSettings
gargoyle - a platform which allows you to switch functionality of your application on/offTasks
celery - an asynchronous task queue/job queue based on distributed message passingForm
django-uni-formNewsletter
emencia-django-newsletter - sending newsletter by email to a contact listDebugging
django-debug-toolbardjango-dtpanel-htmltidy - panel for Django Debug Toolbar which display HTML Validation errors
Labels:
django
Jun 17, 2011
Как в администрировании Django сделать action без обязательного выбора чекбокса
Есть action создания контактов для emencia-django-newsletter из ордеров
Стандартно, если в списке не выбран ни один чекбокс, action не срабатывает. Нужно переписать метод admin.ModelAdmin.response_action:
def make_mailing_list_all(self, request, queryset):
from emencia.django.newsletter.models import Contact
from emencia.django.newsletter.models import MailingList
subscribers = []
for order in OrderRecurring.objects.filter(status='active'):
contact, created = Contact.objects.get_or_create(email=order.customer_email,
defaults={'first_name': order.customer_first_name,
'last_name': order.customer_last_name,
'content_object': order})
subscribers.append(contact)
new_mailing = MailingList(name='All Order recurrings mailing list',
description='New mailing list created from all order recurrings')
new_mailing.save()
new_mailing.subscribers.add(*subscribers)
new_mailing.save()
self.message_user(request, '%s succesfully created.' % new_mailing)
make_mailing_list_all.short_description = _('Create a mailing list for all active recurring orders')
actions = ['make_mailing_list_all',]
Стандартно, если в списке не выбран ни один чекбокс, action не срабатывает. Нужно переписать метод admin.ModelAdmin.response_action:
def response_action(self, request, queryset):
from django.contrib.admin import helpers
try:
action_index = int(request.POST.get('index', 0))
except ValueError:
action_index = 0
data = request.POST.copy()
data.pop(helpers.ACTION_CHECKBOX_NAME, None)
data.pop("index", None)
try:
data.update({'action': data.getlist('action')[action_index]})
except IndexError:
pass
action_form = self.action_form(data, auto_id=None)
action_form.fields['action'].choices = self.get_action_choices(request)
if action_form.is_valid():
action = action_form.cleaned_data['action']
func, name, description = self.get_actions(request)[action]
selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
### CHANGED ###
if not selected:
if action == u'make_mailing_list_all':
pass
else:
return None
else:
queryset = queryset.filter(pk__in=selected)
response = func(self, request, queryset)
### END CHANGED ###
if isinstance(response, HttpResponse):
return response
else:
return HttpResponseRedirect(".")
Labels:
admin,
django,
django 1.1
Subscribe to:
Posts (Atom)