Перейти до основного вмісту

Заміна сигналу m2m_changed для Django 1.1.x

Зіткнувся тут з необхідністю використовувати в проекті сигнал на зміну зв'язку "багато до багатьох". Для тих, хто з цим не стикався, коротко поясню. Ось приклад:
"Необіхдно виконати деякі дії над користувачем у виапдку, коли його включають в групу, або виключають з неї".
В Django 1.2.x існує прекрасний сигнал m2m_changed для обробки таких подій, чого не було у версії 1.1.x, про яку я зараз і пишу.
Перше, що приходить в голову - писати їендлер сигналу post_save для моделі django.contrib.auth.User. Але, спробувавши це зробити, ми побачимо, що в хендлері сигналу ми отримали зміни в об'єкті-користувачі, але групи, в які він включений, не змінились. Проблема в тому, що зв'язок "багато-до-багатьох" відбувається через додаткову таблицю, і на цьому етапі ми не отримуємо зміни, оскільки вони ще не відбулись.
Є декілька шляхів вирішення даної задачі, які підходять при різних вимогах.
1. Створюємо свій власний менеджер моделей (django.db.models.Manager)
Даний підхід, мабуть, вийде найбільш універсальним для даної задачі. Створивши свій менеджер, можна перевизначити методи add, clear, додавши туди необхідну поведінку. Таким чином, вказуємо дії, які можна виконати, в одному місц.
2. Запам'ятовуємо змінені об'єкты, і робимо подальшу обробку в запланованій задачі.
Цей варіант підійде тільки тоді, коли вплив змін є некритичним для роботи проекту, а дії можуть бути виконані через певний час після внесення змін в об'єкти.
3. Використовуємо save_model класу ModelAdmin.
Метод save_model цікавий тим, що отримує в якості аргументів, крім моделі, ще й форму, що дозволяє порівняти старий стан об'єкту і новий через form.cleaned_data, на базі чего можна виконати необхідні додаткові дії. Використовувати варто тоді, коли гарантується зміна моделі через адміністративну частину сайту.
4. Виконуємо дії у view чи чи формі при збереженні об'єкту.
Аналогічно до попереднього методу, тільки так протрібно робити у всіх формах і в'юхах, які приймають участь в зміні потрібного атрибута об'єкта.

Коментарі

Популярні дописи з цього блогу

Регулярні вирази в Python: вивчення та оптимізація

Writing a regular expression is more than a skill -- it's an art. Jeffrey Friedl Що це таке? Рано чи піздно майже кожному програмісту в своєму житті доводиться стикатись з регулярними виразами. Термін "Регулярні вирази" є перекладом з англійської словосполучення "Regular expressions" і не є зовсім точним, а для тих, хто перший раз почув цей термін, мабуть, навіть спантеличуючим (я, наприклад, коли вперше почув, ніяк не міг собі второпати по назві, хоча б приблизно, що це, і для чого використовується). Літературний і більш осмислений переклад звучав би, мабуть, як "шаблонні вирази". Але назва вже прижилась, а скажете "шаблонні вирази" - вас просто не зрозуміють :). Звідси: Регулярний вираз -  це рядок, що задає шаблон пошуку під-рядків в рядку. Регулярні вирази використовуються для аналізу текстів на предмет відповідності текстової інформації деякому шаблону. Наприклад , шаблон, що задає слово, яке містить букву "к". Де застосовують

Python: як програмно перемкнути розкладку клавіатури в Windows

Дослідивши дане питання, я побачив, що Python не має засобів "з коробки" для вирішення цієї задачі. Відвоідно, задача повинна вирішуватись для каждої ОС своїм шляхом. Дане рішення було знайдено мною для ОС Windows XP +. Панацея - Win API Для того, щоб виконати завдання необхідно встановити додатково бібліотеку pywin32 , яка надає доступ до функцій Windows API з Python. З цієї бібліотеки нам знадобиться модуль win32api . >>> import win32api Дослідивши його вміст, можна побачити, що для роботы з розкладкою клавіатури є декілька функцій і одне системне повідомлення Windows - WM_INPUTLANGCHANGE : GetKeyboardLayout GetKeyboardLayoutList LoadKeyboardLayout В даному випадку для нас важлива саме остання функція - LoadKeyboardLayout . Дана функція завантажує нову розкладку (якщо вона ще не завантажена) і виконує після цього ще якісь дії; приймає в якості аргументів два: рядок з ідентифікатором розкладки. дію. Більш детально про їхні можливі значення можна почитати в MSDN . О

wxPython: Gif-анімація і прозорість

Коротко про анімацію в wxPython Дядечко робить анімацію на wxPython В wxPython засоби для роботи з анімацією - це пакет wx.animate . Пакет досить нехитрий - всього декілька класів, з яких частіше за все в роботі використовуються 2: wx.animate.Animation - інкапсулює параметри анімації, а також підтримує завантаження анімації з файлу. Підтримує Gif і Ani   формати анімацій. wx.animate.GifAnimationCtrl - Контрол для рендера і Gif-анімації в графічному інтерфейсі додатку. Останній - дуже класний засіб, оскільки дозволяє фактично в декілька рядків додати в вікно готовуу анімацію: ag_fname = r"progress.gif" ag = wx.animate.GIFAnimationCtrl(self, -1, ag_fname, pos=(0, 0), size=(64,64)) ag.GetPlayer().UseBackgroundColour(True) ag.Play() Досить непогано. І навіть більше ... прозорість. Прозрачность Третій рядок наведеного коду натякає нам, що анімація буде використовувати замість кольору, який в ній встановлений прозорим - фоновий колір вікна. Кажуть, що на GTK воно так і