Przejdź do zawartości

Pole Many2One w Odoo — Kompletny Przewodnik

Praktyczny przewodnik po polu Many2One w modelu danych Odoo — od podstawowego zastosowania, przez logikę relacyjną, aż po możliwości technicznej rozbudowy.
6 marca 2026 przez
Pole Many2One w Odoo — Kompletny Przewodnik
Dasolo
| Brak komentarzy na ten moment

Wprowadzenie


Pole Many2One to jeden z filarów modelu danych w Odoo. Gdy przypisujesz zamówienie sprzedaży do kontrahenta, kwalifikujesz produkt do kategorii czy przypisujesz zadanie do projektu — korzystasz właśnie z relacji Many2One. To najczęściej spotykany typ relacyjny w Odoo, dlatego jego znajomość jest niezbędna dla każdego, kto poważnie zajmuje się rozwojem lub dostosowywaniem systemu.


Z punktu widzenia biznesu, to właśnie pola Many2One sprawiają, że Odoo działa jako zintegrowane narzędzie. Bez nich moduły funkcjonowałyby jak osobne wyspy danych — z nimi informacje płyną pomiędzy dokumentami, a użytkownicy mogą przeskakiwać między powiązanymi rekordami bez zastanawiania się nad strukturą bazy.


W tym przewodniku wyjaśnimy, co dokładnie przechowuje pole Many2One, jak zachowuje się w ORM i interfejsie, jak je tworzyć w Odoo Studio i w Pythonie oraz pokażemy praktyczne scenariusze z CRM, Sprzedaży, Magazynu i Księgowości.

Czym jest pole Many2One w Odoo


W warstwie ORM Many2One oznacza, że rekord z bieżącego modelu wskazuje dokładnie jeden rekord w modelu docelowym. Nazwa odzwierciedla perspektywę bieżącego modelu: wiele rekordów tutaj może wskazywać na jeden rekord tam. Przykładowo wiele zamówień sprzedaży może wskazywać na jednego klienta, a wiele produktów może należeć do jednej kategorii.


Na poziomie bazy danych pole Many2One to zwykły klucz obcy w tabeli bieżącego modelu. Jeśli zamówienie ma przypisanego klienta o ID 42, kolumna partner_id w tabeli sale_order przechowuje wartość 42. Odoo zajmuje się wykonaniem joinów i pobraniem czytelnej nazwy powiązanego rekordu.


W interfejsie pole Many2One wygląda najczęściej jak rozwijane pole z podpowiedzią (typeahead). Użytkownik zaczyna wpisywać nazwę, a Odoo na żywo filtruje pasujące rekordy. Po wybraniu wartość jest ustawiana, a widoczną informacją jest czytelna nazwa powiązanego rekordu — nie jego numer wewnętrzny — co zdecydowanie poprawia komfort pracy.

Przykład definicji pola w Pythonie:


from odoo import fields, models

class SaleOrder(models.Model):
    _inherit = 'sale.order'

    x_account_manager_id = fields.Many2one(
        comodel_name='res.users',
        string='Account Manager',
        ondelete='set null',
    )

Parametr comodel_name wskazuje techniczną nazwę modelu, do którego linkujesz. ondelete określa, co ma się stać z rekordem wskazującym, gdy rekord docelowy zostanie usunięty. Możliwe wartości to cascade (usuń także rekord wskazujący), set null (wyczyść powiązanie) oraz restrict (zabroń usunięcia, jeśli ktoś do niego wskazuje).


W Odoo Studio pole Many2One znajdziesz w zestawie dostępnych pól pod etykietą Many2One. Po przeciągnięciu na formularz wybierasz model docelowy z listy, a Studio automatycznie tworzy pole. To szybki sposób na utworzenie relacji bez pisania kodu.

Zasada działania pola


Czytając Many2One przez ORM otrzymujesz recordset zawierający powiązany rekord — jeśli pole jest puste, otrzymasz pusty recordset. W Pythonie możesz od razu odwołać się do powiązanego rekordu i jego pól używając notacji kropkowej:


order = self.env['sale.order'].browse(1)
customer_name = order.partner_id.name
customer_city = order.partner_id.city

Takie łańcuchowe odwołania są jedną z największych wygód Odoo: nie trzeba ręcznie tworzyć joinów ani dopisywać dodatkowych zapytań — ORM robi to za Ciebie w tle.

Przy odczycie przez XML-RPC Many2One zwraca dwuelementową listę: ID powiązanego rekordu i jego nazwę do wyświetlenia, np. [42, "Acme Corp"]. Jeśli pole jest puste, zwracane jest False. Warto o tym pamiętać podczas przetwarzania odpowiedzi w zewnętrznych skryptach.


Kluczowe atrybuty pola

Poniżej najważniejsze właściwości, które możesz skonfigurować w polu Many2One w Odoo:

  • comodel_name: techniczna nazwa modelu docelowego. To jedyny obowiązkowy parametr.
  • ondelete: zachowanie, gdy rekord docelowy zostanie usunięty. Opcje: 'cascade', 'set null', 'restrict'. Domyślnie 'set null'.
  • domain: filtr ograniczający, które rekordy można wybrać z listy. Na przykład domain=[('customer_rank', '>', 0)] zawęzi wybór partnerów tylko do klientów.
  • context: dodatkowe wartości kontekstu przekazywane przy otwieraniu powiązanego rekordu lub listy. Użyteczne do wstępnego wypełniania pól przy tworzeniu nowego powiązanego rekordu.
  • required: oznacza pole jako obowiązkowe. Rekord nie zostanie zapisany, jeśli pole nie będzie ustawione.
  • readonly: blokuje możliwość zmiany powiązania przez użytkownika. Przydatne, gdy pole ustawiane jest automatycznie i nie powinno być edytowane ręcznie.
  • delegate: jeśli True, pola modelu powiązanego stają się bezpośrednio dostępne w modelu bieżącym — używane do dziedziczenia modeli, nie jako standardowe relacje.

Wygląd w widokach

W formularzu Many2One renderowany jest jako pole z wyszukiwarką i listą podpowiedzi. Użytkownicy mogą wpisywać fragmenty nazwy, a także kliknąć strzałkę przy polu, by otworzyć formularz powiązanego rekordu — to szybki sposób na poruszanie się między powiązanymi dokumentami.


W widokach list Many2One pokazuje nazwę powiązanego rekordu i można po nim grupować listy: np. zamówienia pogrupowane po kliencie lub zadania pogrupowane po projekcie. Grupowanie to jedna z najczęściej używanych funkcji raportowania w Odoo.


W wyszukiwarkach Many2One służy za filtr i kryterium grupowania. Gdy filtrujesz pipeline CRM po kliencie, w rzeczywistości korzystasz z pola Many2One.


Odwrotność: One2Many

Każde Many2One ma naturalne odbicie w postaci One2Many. Jeśli zamówienia wskazują klienta przez Many2One, rekord klienta może pokazywać listę powiązanych zamówień przez One2Many. Dobrą praktyką jest zdefiniowanie obu stron relacji — dzięki temu z poziomu formularza klienta użytkownik zobaczy wszystkie zamówienia bez dodatkowego wyszukiwania. Pole One2Many nie tworzy dodatkowej kolumny w bazie — jest wyliczane na podstawie klucza obcego po drugiej stronie.

Przykłady zastosowań biznesowych


Pole Many2One występuje niemal w każdym standardowym wdrożeniu Odoo. Poniżej pięć praktycznych przykładów z codziennej pracy.


CRM: przypisanie leadów do handlowców

W module CRM lead ma pole user_id — Many2One do res.users — co oznacza odpowiedzialnego handlowca. Menedżerowie mogą filtrować pipeline po osobie, analizować konwersje na poziomie handlowca i masowo przypisywać leady. Dzięki Many2One segmentacja i raporty działają bez konieczności programowania. Jeśli potrzebujesz dodatkowego opiekuna czy account managera, wystarczy dodać kolejne Many2One do tego samego modelu.


Sprzedaż: powiązanie zamówień z klientami i cennikami

Zamówienie sprzedaży zwykle ma co najmniej dwa pola Many2One: partner_id (klient → res.partner) oraz pricelist_id (cennik → product.pricelist). Po wybraniu klienta Odoo może automatycznie uzupełnić cennik, warunki płatności i adres dostawy na podstawie danych kontrahenta. Takie automatyczne uzupełnienia realizowane są przez onchangey, które czytają Many2One i wypełniają powiązane pola — to jeden z najpraktyczniejszych efektów dobrze zaprojektowanego modelu danych.


Magazyn: produkty i kategorie

Każdy produkt ma przypisaną kategorię przez Many2One (categ_id na product.template). Kategoria wpływa na konta księgowe kosztu i przychodu, sposób wyceny oraz strategie usuwania z magazynu. Poprawne przypisanie kategorii jest kluczowe dla rzetelnych raportów finansowych. Many2One upraszcza ten proces: jedno pole wyboru kategorii dla produktu, jedna karta kategorii współdzielona przez setki produktów.


Księgowość: zapisy i dzienniki

Każdy wpis księgowy jest powiązany z dziennikiem przez Many2One (journal_id na account.move). Dziennik decyduje o numeracji dokumentów, rodzaju zapisu (sprzedaż, zakup, bank itp.) i domyślnych kontach. Błędny wybór dziennika na fakturze czy płatności może umieścić zapis w niewłaściwej części księgi — stąd pole Many2One pełni też funkcję kontroli poprawności danych księgowych.


Zarządzanie projektami: zadania i projekty

W module Project zadanie należy do projektu przez Many2One (project_id na project.task). To pojedyncze powiązanie decyduje o ścieżce etapów, uprawnieniach zespołu oraz rozliczaniu czasu pracy. Dla firm usługowych, które fakturują projektowo, relacja między timesheetami, zadaniami i projektem jest podstawą rozpoznawania przychodów i poprawnego fakturowania.

Tworzenie i dopasowywanie pola Many2One


Sposoby dodawania pola Many2One


Są trzy podstawowe drogi dodania Many2One, w zależności od kontekstu technicznego i sposobu wdrożenia.

Odoo Studio (bez kodu)

  1. Odoo Studio to narzędzie low-code dostępne w systemie. Aby dodać Many2One bez pisania kodu:
  2. Uruchom Odoo Studio z menu głównego.
  3. Przejdź do formularza, na którym chcesz dodać pole.
  4. Przeciągnij pole Many2One z panelu pól na formularz.
  5. W panelu właściwości wybierz model docelowy z listy.
  6. Ustaw etykietę pola i ewentualny filtr domain, aby ograniczyć możliwe wybory.

Zapisz i zamknij Studio.


Studio utworzy pole z prefiksem x_studio_ i doda je do widoku. Pole działa od razu: użytkownicy mogą wyszukiwać i wybierać powiązane rekordy. To najszybszy sposób na rozbudowę formularza o relację bez umiejętności programistycznych.

Definiowanie w Pythonie (moduł niestandardowy)


Dla deweloperów Many2One definiujemy w Pythonie — to rekomendowana metoda przy pracy modułowej, kontroli wersji i wdrożeniach wielośrodowiskowych:

from odoo import fields, models class ProjectTask(models.Model): _inherit = 'project.task' x_client_contact_id = fields.Many2one( comodel_name='res.partner', string='Client Contact', domain=[('type', '=', 'contact')], ondelete='set null', help='The main contact at the client for this task.', )


Po zdefiniowaniu pola w modelu dodaj je do odpowiedniego widoku w XML i zaktualizuj moduł, aby zmiany trafiły do bazy. Ta metoda daje pełną kontrolę nad domain, zachowaniem ondelete oraz integracją z metodami compute i constraint — standardowy sposób pracy z relacjami w produkcyjnych modułach Odoo.


Dobrą praktyką jest też utworzenie odwrotnego pola One2Many na modelu powiązanym, aby nawigacja była dwukierunkowa:

class ResPartner(models.Model): _inherit = 'res.partner' x_task_ids = fields.One2many( comodel_name='project.task', inverse_name='x_client_contact_id', string='Related Tasks', )

Przez XML-RPC (programowo)


Jeśli zarządzasz konfiguracją Odoo zdalnie lub automatyzujesz tworzenie pól, możesz stworzyć Many2One przez XML-RPC API:

field_id = models.execute_kw( ODOO_DB, uid, ODOO_API_KEY, 'ir.model.fields', 'create', [{ 'name': 'x_client_segment_id', 'field_description': 'Client Segment', 'model_id': model_id, 'ttype': 'many2one', 'relation': 'res.partner.category', 'on_delete': 'set null', 'state': 'manual', }] )

Dobre praktyki


Klucz relation określa model docelowy, a on_delete jego zachowanie przy usunięciu. Tworząc pole przez API pamiętaj, aby również dodać odwrotne One2Many — to warunek, by pełna nawigacja działała po obu stronach relacji.

1. Zawsze twórz odwrotne One2Many


Gdy dodajesz Many2One, zadbaj o odpowiadające mu One2Many po drugiej stronie. Nie generuje to dodatkowej kolumny w bazie, ale znacząco ułatwia użytkownikom poruszanie się po danych. Bez odwrotnego pola użytkownik formularza klienta nie zobaczy powiązanych z nim zamówień czy zadań bez ręcznego wyszukiwania.

2. Ograniczaj wybór przez domain


Pole Many2one do res.partner bez filtra pokaże wszystkie typy partnerów — dostawców, klientów, adresy dostaw i kontakty wewnętrzne. Jeśli pole ma sens tylko dla klientów, ustaw domain=[('customer_rank', '>', 0)]. Dzięki temu lista będzie czytelniejsza, a użytkownicy nie wybiorą przypadkowych rekordów, które mogą zepsuć dalsze procesy.

3. Przemyśl ondelete


ondelete ma realne konsekwencje: cascade usunie wszystkie rekordy wskazujące na rekord docelowy, co przy nieostrożnym zastosowaniu może doprowadzić do masowych utrat danych. W większości przypadków bezpieczniejszy jest set null — link zostanie wyczyszczony, ale dane pozostaną. Stosuj restrict, gdy rekord docelowy nie powinien być kasowany, jeśli ktoś na niego wskazuje (np. kategoria produktu z przypisanymi produktami).

4. Nie duplikuj danych zamiast Many2One


Częstym błędem jest dodawanie pola typu char, żeby zapisać nazwę firmy lub kategorię, zamiast wskazać istniejący rekord w innym modelu. Taka duplikacja utrudnia filtrowanie, grupowanie i prowadzi do niespójności przy zmianie nazw. Jeśli dane istnieją w innym modelu — użyj Many2One.

5. Wykorzystuj context do wstępnego wypełniania

Najczęstsze pułapki


Atrybut context pozwala przekazać domyślne wartości przy tworzeniu powiązanego rekordu z poziomu lista/pola. Dzięki temu przy tworzeniu kontaktu z poziomu projektu możesz automatycznie ustawić projekt na nowym rekordzie, co oszczędza czas i poprawia spójność danych.

Zapomnienie o odwrotnym One2Many


Najczęstszy błąd przy dostosowaniach Odoo to dodanie Many2One bez zdefiniowania odwrotnego One2Many. Efekt to jednokierunkowe powiązanie: z poziomu jednego rekordu widzisz link, ale z poziomu rekordu docelowego nie masz wglądu, kto wskazuje na niego. Użytkownicy będą narzekać, że nie mogą znaleźć powiązanych dokumentów, a ktoś w końcu zbuduje raport lub wyszukiwarkę jako obejście.

Używanie cascade bez przemyślenia


Ustawienie ondelete='cascade' dla relacji między rekordami operacyjnymi a rekordem nadrzędnym może prowadzić do poważnej utraty danych. Jeśli kategoria produktu zostanie usunięta i wszystkie produkty mają cascade, wszystkie produkty znikną. Zwykle lepsze są set null lub restrict dla danych biznesowych.

Nie sprawdzanie pustych wartości w Pythonie


Gdy Many2One jest pusty, odczyt w Pythonie zwraca pusty recordset, który jest falsy. Jeśli kod robi order.partner_id.name bez wcześniejszego sprawdzenia partner_id, otrzymasz pusty string zamiast błędu — co często jest akceptowalne, ale przy głębszym łańcuchu (order.partner_id.country_id.name) każda pusta część sprawi, że wynik będzie pusty, co może skrycie zafałszować raporty. Sprawdzaj obecność powiązań, jeśli pole nie jest obowiązkowe.

Wskazywanie na niewłaściwy model


Model res.partner w Odoo zbiera klientów, dostawców, kontakty i firmy. Many2One do res.partner bez filtra pokaże wszystkie typy — jeśli pole miało być tylko dla klientów, brak domain spowoduje, że w dropdownie pojawią się wewnętrzni użytkownicy, adresy dostaw czy kontakty dostawców. Zdefiniuj domain zgodnie z rzeczywistym przeznaczeniem pola.

Nadużywanie Many2One tam, gdzie wystarczy Selection

Podsumowanie


Jeśli zestaw wartości jest stały i niewielki, prostsze i bardziej wydajne będzie pole Selection. Many2One wymaga dodatkowego modelu z rekordami i dodaje join do zapytań. Dla statusów z trzema–czterema opcjami lepszy będzie Selection; Many2One wybieraj, gdy wartości są liczne, zarządzane przez użytkowników lub współdzielone między modelami.


Pole Many2One łączy dane między modułami Odoo. Zrozumienie go to nie tylko sprawa dewelopera — analitycy biznesowi, konsultanci funkcjonalni i zaawansowani użytkownicy korzystający ze Studio również zyskują, wiedząc, kiedy i jak stosować Many2One oraz na co zwracać uwagę.


Najważniejsze zasady: zawsze dodawaj odwrotne One2Many, używaj domain, aby listy były czytelne, świadomie wybieraj ondelete i nie stosuj Many2One tam, gdzie prosty Selection wystarczy.

Niezależnie od tego, czy konfigurujesz pole przez Studio, tworzysz moduł w Pythonie czy zarządzasz modelem przez XML-RPC, poprawne zdefiniowanie relacji od początku sprawia, że wdrożenie będzie stabilniejsze i łatwiejsze w utrzymaniu. W Dasolo wspieramy firmy we wdrażaniu, dostosowywaniu i optymalizacji Odoo w całej organizacji. Jeśli potrzebujesz pomocy w zaprojektowaniu przejrzystego modelu danych, dodaniu relacji do formularzy lub zbudowaniu modułu od podstaw, jesteśmy do dyspozycji. Skontaktuj się z nami

Pole Many2One w Odoo — Kompletny Przewodnik
Dasolo 6 marca 2026
Udostępnij ten artykuł
Zaloguj się by zostawić komentarz

Czytaj następne
Pole One2many w Odoo — Kompletny Przewodnik dla Deweloperów
Pole One2many w Odoo — co to daje, kiedy je stosować i jak wprowadzić je w modelu danych Pole One2many to podstawowy sposób modelowania relacji „jeden do wielu” między rekordami w systemie Odoo. Pozwala ono powiązać pojedynczy rekord (np. fakturę, zamówienie czy klienta) z wieloma powiązanymi rekordami (pozycjami faktury, pozycjami zamówienia, adresami). Dzięki temu dane są uporządkowane: główny obiekt przechowuje nagłówek, a powiązane obiekty przechowują szczegóły. Kiedy użyć One2many Stosuj One2many, gdy chcesz odwzorować relację, w której jeden element kontroluje zbiór powiązanych pozycji — na przykład: zamówienie → linie zamówienia, produkt → zdjęcia, klient → wiele adresów. To rozwiązanie sprawdza się, gdy powiązane rekordy mają sens tylko w kontekście rekordu nadrzędnego albo gdy potrzebujesz wygodnego widoku listy edytowalnych elementów bez opuszczania formularza głównego. Jak zaprojektować model danych z One2many W Odoo relacja One2many jest zawsze sprzężona z polem Many2one po drugiej stronie. W praktyce definicja polega na: - Dodaniu pola Many2one w modelu „wiele” (np. order_line ma field order_id jako Many2one do order). - Dodaniu pola One2many w modelu „jeden” wskazującego na pole Many2one (np. order ma field order_line_ids jako One2many('sale.order.line', 'order_id')). Przykład implementacji w Pythonie (szablon): - Model nadrzędny: class sale_order(models.Model): _name = 'sale.order' order_line_ids = fields.One2many('sale.order.line', 'order_id', string='Order Lines') - Model podrzędny: class sale_order_line(models.Model): _name = 'sale.order.line' order_id = fields.Many2one('sale.order', string='Order Reference', ondelete='cascade') Ważne parametry i zachowania - ondelete='cascade' usuwa pozycje powiązane przy usunięciu rekordu nadrzędnego — przydatne, gdy nie chcesz pozostawiać osieroconych rekordów. - inverse_name: w One2many wskazuje pole Many2one — to powiązanie jest obowiązkowe. - readonly oraz context mogą sterować zachowaniem widoku i sposobem edycji linii w formularzu. Widoki i edycja w UI W XML formularza zwykle definiujesz pole One2many jako tree (lista) lub jako listę z możliwością wierszowej edycji. Dzięki temu użytkownik może dodawać, usuwać i edytować powiązane rekordy bez przechodzenia do osobnego widoku. Pamiętaj o poprawnym ustawieniu domain, context i widget, jeśli chcesz ograniczyć lub ułatwić wybór powiązanych elementów. Zalety i pułapki Zalety: - Klarowna organizacja danych i lepsza nawigacja w UI. - Możliwość masowej edycji powiązanych rekordów bez przełączania widoków. Pułapki: - Duże zbiory powiązanych rekordów mogą spowolnić ładowanie formularza — rozważ paginację lub widok kanban/tree z ograniczeniem. - Niewłaściwe ustawienie ondelete może prowadzić do utraty danych lub pozostawienia rekordów bez odniesienia. Wskazówki praktyczne - Zawsze definiuj Many2one w modelu „wiele” i upewnij się, że One2many wskazuje na właściwe pole. - Używaj ondelete świadomie (cascade vs. set null). - Przy dużej liczbie linii rozważ użycie paginacji lub widoku listy zamiast ładowania wszystkich rekordów jednocześnie. - Testuj zachowania w UI: dodawanie, kopiowanie, usuwanie i zapisywanie — to najczęstsze miejsca, gdzie pojawiają się błędy projektowe. Podsumowanie Pole One2many to naturalne narzędzie w Odoo do modelowania relacji jeden–wiele. Daje porządek i wygodę w obsłudze powiązanych danych, o ile zostanie poprawnie zaprojektowane — czyli z odpowiednim polem Many2one po drugiej stronie, przemyślanym ondelete i zoptymalizowanym widokiem dla dużych zbiorów.