Работа и вакансии для программистов
В связи с участившимися вопросами о поиске программистов и интересных вакансий, решил организовать у себя в блоге отдельный раздел.
Я уверен, что работа или сотрудник, найденные по личным рекомендациям, имеют больший шанс удовлетворить запросы как работодателя, так и соискателя. Так получилось, что у меня много друзей в реальном и виртуальном мире — программисты, разработчики, админы и другие ИТ-специалисты. Многие из них работают уже в менеджменте или на топовых позициях, плюс ко мне периодически обращаются компании и люди, которых я консультирую с просьбой помочь в поиске сотрудников. Поэтому, для небольшой организации процесса нахождения работодателей и соискателей я решил вести личную базу вакансий и резюме. Также я буду рад помочь моим читателям в этом вопросе.
Чаще всего ищутся разработчики со знанием Python, Ruby и JavaScript. Если вы пишите на PHP, CSS/HTML, хороший управленец, пиарщик или занимаетесь веб-дизайном, также добавьте ваше резюме.
Мои партнеры чаще всего предлагают контрактную работу в западных стартапах или рунет-проектах. Если вы тоже работодатель или вы просто ищите специалиста, пишите мне на личную почту dobrych [at] gmail.com
На сегодня есть две позиции, на которые требуются специалисты с опытом:
- Ruby программисты для разработки и поддержки сайтов, построенных на Rails.
- JavaScript программист с знанием ExtJS.
Последняя свежая информация и анкета для соискателя всегда на странице «Работа и вакансии».
Для работодателей есть возможность размещения баннеров и выделенных объявлений (виджетов).
Django signals по-новому 1
На пути к 1.0 релизу Django претерпевал немало радикальных изменений. Одно из них рефакторинг системы сигналов.

Если вы первый раз читаете и не в курсе «что это такое и с чем его едят», то скажу в двух словах. Это система реагирования на события приложения. Любой JavaScript или прикладной UI программист хорошо знаком с системой событий (event) — клик мышкой, нажатие горячей клавиши и т.п. Для программистов серверной части веба все выглядит немного по другому. Есть HTTP-запрос и есть его обработчик, анализируется как правило URL на предмет «кому отправлять запрос». Но на самом деле это та же система сигналов-событий, только узкопрофилированная под обработку HTTP-запросов.
Оказывается серверная часть веб-приложения тоже может, и я уверен, просто должна генерировать намного больший спектр сигналов, чем просто обработку URL и данных запроса. С чем успешно и справляется Django. Теперь немного прозы. Какие же события может ловить Django «из-коробки».
pre_init— перед запуском метода-конструктора__init__()модели;post_init— после выполнения метода__init__()модели;pre_save— перед сохранением экземпляра модели в базу;post_save— после успешного сохранения экземпляра модели в базу;pre_delete,post_delete— перед и после удаления экземпляра модели из базы;post_syncdb— генерируется админкой Django после установки нового приложения (INSTALLED_APPS);request_started,request_finished,got_request_exception— генерируются при обработке HTTP-запросов;template_rendered— генерируется только в режиме тестирования приложения.
Итак сигналы *_init, _*save, *_delete и post_syncdb генерируются системой моделей Django и их можно импортировать из django.db.models.signals.
Сигналы обработки HTTP-запросов из django.core.signals. И тестовый template_rendered из django.test.signals.
А теперь реальный пример, как повесить обработчик на событие-сигнал сохранения модели. В нашем случае будет требоваться определить тип mime закачанного файла перед его сохранением в базу.
Код модели:
class MimeType(models.Model):
"""
Mime Types table
"""
name = models.CharField(max_length=200)
slug = models.SlugField()
def __unicode__(self):
return self.name
class Item(models.Model):
"""
Main file
"""
name = models.CharField(max_length=200)
slug = models.SlugField()
file = models.FileField(upload_to='files', blank=True)
mime = models.ForeignKey(MimeType, blank=True, null=True)
upload_date = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return self.name
def set_mime(self, mime):
obj, created = MimeType.objects.get_or_create(name=mime, slug=slugify(mime))
self.mime = obj
Посмотрите на метод set_mime модели Item. Он создает новый объект MimeType или использует если он уже создан.
При этом не сохраняя модель Item. Теперь я пишу функцию-callback, которая будет вызываться по событию сохранения модели Item.
import mimetypes
import os.path
# init mime types dict
mimetypes.init()
def add_mime_type(instance, **kwargs):
"""
Adding mime-type to uploaded file (for future use).
Would be called on post-save.
"""
if not hasattr(instance, 'mime') or not hasattr(instance, 'file'):
raise Exception("Object %s does not have 'mime' attribute! Can't set mime-type!" % instance)
if instance.file:
extension = os.path.splitext(instance.file.path)[1].lower()
instance.set_mime(mimetypes.types_map[extension])
Итак, функция-callback add_mime_type принимает параметр instance, который является экземпляром модели, сгенерировавшим сигнал (в нашем случае модели Item). Вторым параметром принимает словарь (dictionary). Кстати, это и есть один из моментов обратной несовместимости. После рефакторинга каждая функция-callback должна принимать параметр **kwargs.
Теперь третий самый простой шаг — связывание модели с сигналом. В самом конце файла моделей добавилась строчка:
models.signals.pre_save.connect(add_mime_type, sender=Item)
Теперь перед каждым сохранением объектов Item, будет выполняться проверка и установка Mime-типа.
Кстати, я советую если у вас больше одного сигнала, выносите их в отдельный файл signals.py или можно по-старинке писать в файле моделей (что ИМХО иногда мешает чтению кода).
Почитать про сигналы можно еще в официальной доке: Django Signals и Django Built-in signal reference. Почитать про рефаторинг можно на странице Backwards Incompatible Changes и в соответствующем коммите 8223.
Александр Кошелев тоже немного раньше написал по теме, статья «А вы поймали новые сигналы?» с хорошим примером создания абстрактного сигнала.
«На сегодня все. Вопросы в студию» :-)
Django 1.0
Не буду говорить насколько релиз важен или наоборот нет. Я в целом разделаю точку зрения Ивана. Но думаю, что как раз релиз является отличным поводом написать много новых заметок, статей и примеров кода по новым и переделанным фичам.
Так что ждите в скором будущем новых статей по Django тематике. Думаю осветить подробно:
- эффективное создание форм;
- кастомизация django admin интерфейса;
- трюки с FileField и аплоадом в общем;
- сигналы в django.






