Jeśli spędziłeś trochę czasu przy ORM Odoo lub przy dopasowywaniu widoków, na pewno natknąłeś się na pojęcie kontekstu. Pojawia się ono w definicjach pól, atrybutach XML widoków oraz w kodzie Python. Dla wielu konsultantów i programistów kontekst działa bez widocznego wysiłku—aż w końcu coś przestaje działać i trzeba zrozumieć, co poszło nie tak.
Znajomość kontekstu to nie teoria — wpływa on bezpośrednio na zachowanie modelu danych: jakie wartości wstępnie wypełniają formularze, które rekordy są widoczne, oraz jak liczone są pola zależne. Niezależnie czy robisz prostą modyfikację Odoo, czy tworzysz cały moduł, poprawne użycie kontekstu oszczędza masę czasu spędzonego na debugowaniu.
Ten przewodnik wyjaśnia, czym jest kontekst, jak przepływa przez ramy Odoo i jak bez obaw stosować go w praktycznych wdrożeniach.
Czym jest kontekst w Odoo
W Odoo kontekst to po prostu słownik Pythona, który towarzyszy każdemu żądaniu, wywołaniu metody i operacji na rekordach. To nie jest typ pola w sensie ORM — nie znajdziesz fields.Context(). Kwestia polega na tym, że kontekst zmienia sposób działania pól i metod.
Można go postrzegać jako niewidoczne instrukcje dołączone do operacji: mówią Odoo, aby wstępnie wypełnić pole, pokazać także archiwalne rekordy, obliczać teksty w innym języku lub zastosować określony filtr przy wybieraniu powiązanych rekordów.
Gdzie pojawia się kontekst
Kontekst spotkasz głównie w trzech miejscach w modelu danych Odoo:
- W definicjach pól w Pythonie: parametr
contextprzy polach relacyjnych takich jak Many2one, One2many i Many2many. - W atrybutach widoków w XML: atrybut
contextna tagach<field>w formularzach, listach i kanbanach. - W środowisku ORM: dostęp przez
self.env.contextw Pythonie i modyfikowalny poprzezself.with_context(key=value).
We wszystkich tych miejscach kontekst pełni tę samą rolę: niesie dodatkowe informacje, które kształtują zachowanie pola lub rekordu w czasie działania systemu.
Jak działa kontekst w modelu danych Odoo
Kontekst przepływa przez cykl obsługi żądania od otwarcia formularza do zapisu rekordu. Poniżej najważniejsze mechanizmy w praktyce.
Domyślne wartości z default_*
Jeden z najczęściej wykorzystywanych wzorców to klucze zaczynające się od default_. Jeśli w kontekście przekazano default_pole, Odoo użyje tego, by wstępnie wypełnić pole przy tworzeniu nowego rekordu.
Przykład: gdy przycisk otwiera formularz zamówienia sprzedaży i w kontekście jest {"default_partner_id": 42}, pole klienta zostanie automatycznie ustawione na partnera o ID 42. Użytkownik zobaczy wypełniony formularz bez dodatkowego kodu Python.
Ten wzorzec jest powszechny w praktycznych rozwiązaniach Odoo, bo pozwala tworzyć płynne nawigacje między rekordami.
Atrybut context na polach relacyjnych
Definiując pole Many2one, One2many lub Many2many w Pythonie, możesz podać parametr context. Ten kontekst zostanie użyty, gdy pole będzie ładować lub tworzyć powiązane rekordy przez popup lub listę wyboru.
Praktyczny przykład: Many2one do res.partner z context={"default_is_company": True} spowoduje, że przy tworzeniu nowego partnera z tego pola checkbox "Firma" będzie zaznaczony. To delikatna podpowiedź dla użytkownika bez narzucania reguły.
Kontekst w widokach XML
W XML widoku atrybut context na tagu pola działa podobnie, ale można go budować dynamicznie — odwołując się do wartości innych pól przy pomocy składni Odoo.
To pozwala tworzyć inteligentne formularze, w których kontekst jednego pola zależy od wartości innego. To podstawowa technika przy dostosowaniach Odoo, gdy chcemy uniknąć dodatkowego kodu Python.
Odczyt i zmiana kontekstu w Pythonie
W dowolnej metodzie modelu możesz odczytać bieżący kontekst przez self.env.context. Otrzymasz cały słownik takim, jakim był przy wywołaniu metody.
Aby wykonać operację z zmienionym kontekstem, użyj self.with_context(key=value). Zwraca to nowy recordset z uaktualnionym kontekstem, nie modyfikując oryginalnego — czysty i bezpieczny sposób pracy z kontekstem.
Popularne wbudowane klucze kontekstowe
Odoo korzysta z kilku zarezerwowanych kluczy kontekstowych, które wywołują określone zachowania w całym systemie:
lang: zmienia język tłumaczonych pól.active_test: ustawione naFalsesprawia, że wyszukiwania uwzględniają rekordy zarchiwizowane.no_recompute: blokuje ponowne przeliczanie przechowywanych pól computed.mail_notrack: wyłącza śledzenie w chatterze przy zapisie.allowed_company_ids: kontroluje widoczność rekordów w modelu wielofirmowym.bin_size: zwraca rozmiary plików zamiast zawartości binarnej dla pól Binary.
Znajomość tych kluczy to elementarz dla każdego programisty Odoo, bo pozwalają sterować zachowaniem bez dodatkowego kodu.
Przykłady zastosowań w biznesie
Kontekst to nie tylko narzędzie programistyczne — rozwiązuje konkretne problemy w procesach biznesowych. Poniżej pięć typowych zastosowań z wdrożeń Odoo.
1. CRM: wstępne przypisanie zespołu sprzedaży przy nowym leadzie
Kierowniczka sprzedaży pracuje na widoku kanban przefiltrowanym dla jej zespołu. Po kliknięciu "Nowy" oczekuje, że lead zostanie przypisany do jej zespołu. Przekazanie default_team_id w kontekście akcji powoduje automatyczne ustawienie pola team już przy otwarciu formularza — mniej błędów przy przypisywaniu.
2. Sprzedaż: domyślna lista cen według segmentu klienta
Przy tworzeniu oferty z poziomu widoku konkretnej grupy klientów, kontekst może ustawić default_pricelist_id zgodnie z kategorią. Sprzedawca otrzymuje właściwą listę cen jako podpowiedź, lecz nadal może ją zmienić.
3. Magazyn: filtrowanie lokalizacji w formularzu przesunięcia
W operacjach magazynowych pole źródłowej lokalizacji w formularzu transferu może mieć kontekst ograniczający wybór tylko do lokalizacji jednego magazynu. To prosty sposób, by zmniejszyć liczbę błędów w konfiguracjach z wieloma magazynami.
4. Księgowość: linie faktury w odpowiednim języku
Przy fakturowaniu klientów zagranicznych klucz lang sprawia, że opisy produktów i linii faktury będą wyświetlane w języku klienta — nawet gdy wewnętrzne dane są w innym języku.
5. Modele niestandardowe: pokazanie produktów zarchiwizowanych w specjalnym widoku
Zespół operacyjny musi przeglądać produkty wycofane razem z aktywnymi. Specjalny widok przekazuje active_test: False w kontekście akcji, dzięki czemu w tym jednym miejscu pojawiają się także produkty zarchiwizowane, bez zmiany logiki w innych miejscach systemu.
Tworzenie i modyfikacja kontekstu dla pól
Są zasadniczo dwa sposoby dodawania lub edytowania kontekstu przy polach: bezkodowo przez Odoo Studio albo technicznie — przez Python i XML. To ważna część każdego technicznego poradnika Odoo dotyczącego zachowania pól.
Korzystanie z Odoo Studio
Odoo Studio pozwala zmieniać niektóre właściwości pól bez programowania. Dla pól relacyjnych Studio udostępnia opcję konfiguracji kontekstu, gdzie można podać domyślne wartości stosowane przy tworzeniu rekordu z poziomu pola.
To wygodne w prostych przypadkach: ustawienie domyślnej firmy, zespołu, kategorii czy odpowiedzialnego użytkownika. Jednak wsparcie Studio dla kontekstu jest uproszczone — jeśli potrzebujesz kontekstu dynamicznego, odwołującego się do innych pól, konieczne będzie rozwiązanie techniczne.
Pamiętaj, że kontekst ustawiony przez Studio jest zapisany bezpośrednio w widoku. Jeżeli później dodasz techniczne rozszerzenie tego samego widoku, musisz uwzględnić istniejący kontekst z Studio, aby uniknąć konfliktów.
Definiowanie kontekstu dla pól w Pythonie
W module niestandardowym kontekst dodajesz bezpośrednio w definicji pola. Dla Many2one parametr context przyjmuje statyczny słownik:
Taki statyczny kontekst będzie stosowany za każdym razem, gdy pole ładuje lub tworzy powiązane rekordy — nie zmienia się on w zależności od innych pól. Jeśli potrzebujesz reaktywnego zachowania, przenieś logikę na poziom widoku.
Definiowanie kontekstu w XML widoków
W XML atrybut context przyjmuje ciąg znaków, który Odoo ewaluje w czasie działania. Możesz odwoływać się do wartości pól, aktualnego użytkownika (uid), aktywnego rekordu (active_id) i innych zmiennych:
Dlatego kontekst na poziomie widoku jest znacznie bardziej elastyczny niż statyczny kontekst pola. To standardowy sposób w frameworku Odoo na budowanie formularzy, w których zachowanie jednego pola zależy od innego — to też sprawdzony sposób, by tworzyć intuicyjne pola dla użytkowników końcowych.
Przekazywanie kontekstu przez akcje okien (Window Actions)
Kontekst można też ustawić na rekordach ir.actions.act_window. To sposób, w jaki menu i przyciski przekazują kontekst do otwieranych widoków. Pole context akcji jest scalane z sesyjnym kontekstem przy ładowaniu widoku.
To najczystsze rozwiązanie dla sytuacji takich jak przykład z zespołem sprzedaży: kontekst leży na akcji, nie na definicji pola, więc różne miejsca nawigacji mogą mieć różne domyślne wartości bez zmian w modelu.
Dobre praktyki
Praca z kontekstem staje się prostsza, gdy przyjmiesz kilka spójnych nawyków — dotyczy to zarówno tworzenia modułu, jak i szybkich dostosowań Odoo.
- Używaj kontekstu jako sugestii, nie przymusu. Domyślne wartości z kontekstu prowadzą użytkowników, ale ich nie blokują. Gdy potrzebujesz twardego ograniczenia, sięgnij po domain lub onchange.
- Umieszczaj kontekst dynamiczny w widokach, nie w definicjach pól. Kontekst na polu jest statyczny — jeśli ma odzwierciedlać stan rekordu, lepiej zrobić to w XML widoku.
- Zamiast modyfikować env.context bezpośrednio, używaj
with_context(). Środowisko Odoo traktuje kontekst funkcjonalnie; twórz nowe środowisko z dodatkami, zamiast zmieniać istniejące. - Przekazuj w kontekście tylko to, co jest potrzebne. Klucze kontekstowe kumulują się podczas wywołań; niepotrzebne wpisy mogą powodować nieoczekiwane zachowania w metodach, które na nie reagują.
- Korzystaj z kontekstu do przekazywania flag do logiki warunkowej. Częsty wzorzec to np.
from_wizard: Truew kontekście — w metodzie compute lub onchange sprawdzasz tę flagę i uruchamiasz inną ścieżkę. Dzięki temu nie trzeba dodawać pól modelu do śledzenia stanu przepływu. - Dokumentuj niestandardowe klucze kontekstowe w module. Klucze kontekstu są niewidoczne gołym okiem — dopisz komentarz lub docstring wyjaśniający, jakie klucze twój moduł czyta lub ustawia. Przywracanie kontekstu po czasie będzie wtedy prostsze.
Częste pułapki
Błędy związane z kontekstem bywają trudne do zdiagnozowania, bo kontekst nie jest widoczny w UI. Oto najczęstsze pomyłki spotykane w projektach.
Traktowanie default_* jak wartości obowiązkowych
Domyślna wartość z kontekstu stosuje się tylko wtedy, gdy rekord tworzy się przez formularz z odpowiednim kontekstem. Gdy rekordy tworzysz programowo przez ORM bez przekazania kontekstu, domyślka nie zostanie zastosowana. Programiści czasem mylą to z parametrem default w definicji pola — to nie to samo. Jeśli zależy ci na domyślnych wartościach przy tworzeniu z kodu, przekaż odpowiedni kontekst explicite.
Bezpośrednia mutacja słownika kontekstu
Słownik kontekstu jest współdzielony na stosie wywołań. Jeśli zmienisz self.env.context w miejscu, możesz nieoczekiwanie wpłynąć na działanie innych fragmentów kodu w tej samej transakcji. Prawidłowy wzorzec to zawsze self.with_context(nowy_klucz=wartosc), który tworzy nowe środowisko z kopią kontekstu i twoimi zmianami.
Przekazywanie zbyt wielu danych w kontekście
Każdy klucz kontekstowy przemieszcza się przez cały łańcuch wywołań. Niektóre metody Odoo sprawdzają obecność konkretnych kluczy i zmieniają sposób działania. Nieoczekiwane klucze mogą przypadkowo uruchomić te ścieżki. Trzymaj kontekst oszczędny i skupiony na bieżącej operacji.
Zapomnienie o active_test przy wyszukiwaniu rekordów archiwalnych
Domyślnie search() i search_read() filtrują rekordy z polem active = False. Jeśli twoja logika ma pracować także na zarchiwizowanych rekordach, musisz jawnie przekazać active_test: False w kontekście. Zapomnienie o tym to częsty błąd przy customizacjach produktów i zapasów.
Konflikty kontekstu między Studio a kodem customowym
Jeżeli Odoo Studio ustawiło kontekst w widoku, a potem dodasz techniczne rozszerzenie tego samego widoku, oba konteksty mogą wejść ze sobą w konflikt lub jeden może nadpisać drugi w zależności od porządku łączenia XML. Zawsze sprawdzaj istniejący kontekst na polu przed dodaniem własnego w dziedziczeniu widoku — szczególnie gdy łączysz pola z Odoo Studio z rozwiązaniami modułowymi.
Podsumowanie
Kontekst to mechanizm, który w tle wykonuje dużo pracy. Kiedy zrozumiesz jego przepływ przez definicje pól, atrybuty widoków i środowisko ORM, zyskasz lepszą kontrolę nad zachowaniem modelu danych.
Najważniejsze wnioski są proste: używaj kluczy default_* by podpowiadać użytkownikom, umieszczaj kontekst dynamiczny w widokach, zawsze stosuj with_context() zamiast modyfikować kontekst w miejscu, i utrzymuj kontekst zwięzły, by nie wpływał niechcianie na inne części systemu.
Niezależnie czy przerabiasz samouczek pól Odoo, tworzysz moduł czy diagnozujesz dziwne zachowanie pola — zrozumienie kontekstu niemal zawsze pomoże znaleźć rozwiązanie.
W Dasolo pomagamy firmom wdrażać, dostosowywać i optymalizować Odoo tak, by odpowiadało realnym procesom biznesowym. Jeśli pracujesz nad zmianą, w której bierze udział kontekst i nie jesteś pewien rozwiązania, albo chcesz omówić swoje wdrożenie, chętnie pomożemy.
Skontaktuj się z naszym zespołem poprzez stronę kontaktową i opisz, co budujesz. Współpracujemy z firmami wszystkich rozmiarów, żeby Odoo działało tak, jak powinno.