Przejdź do zawartości

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.
6 marca 2026 przez
Pole One2many w Odoo — Kompletny Przewodnik dla Deweloperów
Dasolo
| Brak komentarzy na ten moment

Wprowadzenie


Jeśli otworzyłeś kiedyś Zamówienie Sprzedaży w Odoo i pod danymi klienta zobaczyłeś listę pozycji, właśnie zobaczyłeś działające pole One2many. To jeden z podstawowych elementów modelu danych Odoo — zrozumienie go jest niezbędne zarówno dla użytkowników konfiguracyjnych, jak i programistów.


Ten przewodnik wyjaśnia istotę pola One2many, jego działanie w ORM Odoo, typowe scenariusze użycia oraz jak je tworzyć — za pomocą Odoo Studio albo bezpośrednio w kodzie Python.

Niezależnie od tego, czy chcesz lepiej pojąć strukturę danych w swoim systemie, czy potrzebujesz praktycznego „how‑to” jako deweloper, znajdziesz tu najważniejsze informacje.

Czym jest pole One2many w Odoo


Pole One2many to typ relacyjny w Odoo, który pozwala jednemu rekordowi rodzicielskiemu powiązać się z wieloma rekordami potomnymi z innego modelu.


Prosto mówiąc: jedna firma może mieć wiele faktur; jedno zamówienie sprzedaży — wiele pozycji; jeden projekt — wiele zadań. Pole One2many służy do reprezentowania takiej relacji „jeden do wielu”.


W interfejsie Odoo One2many zwykle wyświetla się jako wbudowana tabela w formularzu — dzięki temu użytkownik może dodawać, edytować i usuwać rekordy podrzędne bez opuszczania formularza rodzica.


Czym różni się od innych pól relacyjnych

W ORM Odoo występują trzy podstawowe pola relacyjne:


  • Many2one: rekord wskazuje na pojedynczy rekord innego modelu (np. zamówienie → klient).
  • One2many: rekord rodzica połączony z wieloma rekordami innego modelu (np. zamówienie → pozycje).
  • Many2many: relacja wiele‑do‑wielu, gdzie rekordy po obu stronach mogą łączyć się wzajemnie (np. produkt ↔️ tagi).

One2many stosujemy, gdy każdy rekord potomny ma dokładnie jednego rodzica. Gdy rekordy mają być współdzielone przez wielu rodziców, właściwe będzie Many2many.


Istotne: One2many jest „wirtualne” — samo nie przechowuje wartości w tabeli rodzica. Odczytuje dane z tabeli potomnej przez pole Many2one zdefiniowane po stronie dziecka.

Jak działa to pole


W praktyce oznacza to, że w bazie danych nie powstaje osobna kolumna w tabeli rodzica. Wszystkie wskazania przechowywane są jako klucz obcy w tabeli potomnej.


Zasada jest prosta: każdemu One2many musi odpowiadać pola Many2one w modelu dziecka. One2many to w istocie odwrotne zapytanie — Odoo wyszukuje wszystkie rekordy potomne, których Many2one wskazuje na bieżący rekord rodzica.


Relacja One2many ↔️ Many2one

Definiując One2many w Pythonie, podajesz dwie kluczowe właściwości:


  • comodel_name: nazwa modelu przechowującego rekordy potomne.
  • inverse_name: nazwa pola Many2one w modelu potomnym, które wskazuje na rodzica.

Przykład: w module serwisowym możesz mieć kontrakt usługowy powiązany z wieloma pozycjami deliverable.


deliverable_ids = fields.One2many(
    comodel_name='service.deliverable',
    inverse_name='contract_id',
    string='Deliverables'
)

W tym przykładzie contract_id to pole Many2one zdefiniowane po stronie service.deliverable. Bez niego One2many nie zadziała.


Co dzieje się w bazie danych

W tabeli rodzica nie ma kolumny przechowującej One2many — wszystkie powiązania znajdują się w tabeli potomnej jako kolumna klucza obcego wskazująca ID rodzica.

Kiedy Odoo ładuje formularz rodzica i ma pokazać jego One2many, ORM wykonuje zapytanie SQL: znajdź wszystkie wiersze w tabeli potomnej, których klucz obcy równa się ID bieżącego rodzica. To standardowe zachowanie relacyjnej bazy danych.


Dlatego One2many traktowane jest jako pole „bez kolumny” — widok relacji, a nie przechowywana wartość w tabeli rodzica.

Zastosowania biznesowe


One2many występuje w Odoo tam, gdzie występują naturalne relacje rodzic‑potomek. Poniżej pięć praktycznych przykładów z codziennych procesów biznesowych.


1. Zamówienia sprzedaży i pozycje

W module Sprzedaży model sale.order ma pole order_line_ids, które łączy zamówienie z wieloma rekordami sale.order.line. Każda pozycja zawiera produkt, ilość, cenę jednostkową i rabat — i wszystkie modyfikacje wykonasz bezpośrednio w formularzu zamówienia.


2. Faktury i pozycje faktury

W Księgowości model account.move korzysta z One2many do zarządzania liniami faktury (account.move.line). Każda linia to osobna pozycja rozliczeniowa, a suma faktury jest agregacją tych linii.


3. Projekty i zadania

W module Projektów project.project wykorzystuje One2many do wyświetlania wszystkich zadań należących do projektu — lista może przyjmować formę tabeli, kanbanu czy wykresu Gantta, korzystając z tej samej relacji.


4. Kontrahenci i kontakty powiązane

Model res.partner zawiera pole child_ids, które pokazuje osoby powiązane z firmą. Każdy kontakt ma z kolei pole Many2one parent_id wskazujące na firmę.


5. Modele niestandardowe w serwisie lub produkcji

W modułach szytych na miarę One2many to naturalny wybór wszędzie tam, gdzie jeden rekord „posiada” listę podrzędnych: zlecenie serwisowe z listą części, kurs z wieloma terminami, kontrakt z listą deliverable itd.


Ta elastyczność sprawia, że One2many jest kluczowym narzędziem przy dostosowywaniu Odoo do różnych branż i procesów.

Tworzenie i dostosowywanie pola


Są dwie główne metody dodawania One2many w Odoo: bezkodowo przez Odoo Studio albo przez kod Python w module.


Tworzenie przez Odoo Studio

W Studio nie dodasz One2many bezpośrednio na rodzicu — najpierw musi istnieć pole Many2one po stronie dziecka, bo One2many po prostu odwołuje się do niego.

Polecany przebieg prac w Studio wygląda tak:

  1. Edytuj model potomny w Studio i dodaj pole Many2one wskazujące na model rodzica.
  2. Zapisz zmiany, a następnie wróć do modelu rodzica w Studio.
  3. Dodaj nowe pole typu "One2many" — Studio poprosi o wskazanie modelu powiązanego i nazwy pola inverse (Many2one).
  4. Po dodaniu pole pojawi się jako wbudowana lista w formularzu rodzica.

Dla większości użytkowników biznesowych to najprostszy sposób na utworzenie relacji One2many bez pisania kodu — zachowuje takie same właściwości jak pole stworzone programistycznie.


Tworzenie przez kod Python w module

Deweloperzy, którzy chcą pełnej kontroli nad zachowaniem i nazwami pól, definiują One2many w plikach Pythona. Przykład poniżej pokazuje kompletną definicję kontraktu i elementów deliverable.


from odoo import fields, models

class ServiceContract(models.Model):
    _name = 'service.contract'
    _description = 'Service Contract'

    name = fields.Char(string='Contract Name', required=True)
    deliverable_ids = fields.One2many(
        comodel_name='service.deliverable',
        inverse_name='contract_id',
        string='Deliverables'
    )


class ServiceDeliverable(models.Model):
    _name = 'service.deliverable'
    _description = 'Service Deliverable'

    contract_id = fields.Many2one(
        comodel_name='service.contract',
        string='Contract',
        ondelete='cascade'
    )
    name = fields.Char(string='Description', required=True)

Zwróć uwagę, że pole Many2one (contract_id) musi istnieć po stronie dziecka — inverse_name w definicji One2many musi dokładnie odpowiadać tej nazwie.


Tworzenie pola przez XML‑RPC

Jeżeli zarządzasz polami programowo, możesz tworzyć One2many przez API XML‑RPC, korzystając z modelu ir.model.fields. Reguła jest ta sama: najpierw Many2one, potem One2many z parametrem relation_field wskazującym na nazwę pola Many2one.


Taki sposób sprawdza się przy automatyzacji zmian w wielu środowiskach lub w scenariuszach, gdzie pola tworzone są skryptami.

Dobre praktyki


Na podstawie licznych wdrożeń u klientów warto stosować kilka praktyk, które upraszczają pracę z One2many.


  • Zawsze twórz najpierw Many2one. One2many nie zadziała bez odpowiedniego pola inverse po stronie dziecka — dotyczy to Studio, kodu i API.
  • Używaj sufiksu _ids dla nazw One2many. Konwencja nazewnictwa (np. line_ids, task_ids) od razu mówi, że pole zwraca zestaw rekordów, co ułatwia czytelność kodu.
  • Ustaw ondelete='cascade' gdy to uzasadnione. Jeśli usunięcie rodzica ma usuwać także dzieci, skonfiguruj to na Many2one, by nie zostawiać po sobie osieroconych rekordów.
  • Skup listę w formularzu na najważniejszych kolumnach. Pokazywanie zbyt wielu kolumn spowalnia formularz i utrudnia pracę — używaj atrybutu optional dla mniej istotnych pól.
  • Stosuj filtry (domain) dla ograniczenia widocznych rekordów. Przy współdzielonych modelach domain pomoże pokazać tylko te rekordy potomne, które są relewantne dla danego rodzica.
  • Ostrożnie przy dużych zestawach danych. Gdy rodzic może mieć tysiące dzieci, nie ładuj ich wszystkich na raz. Rozważ osobny widok listy lub paginację w osadzonej tabeli.

Typowe pułapki


Najczęstsze błędy w pracy z One2many


Brak pola inverse (Many2one)

Najczęstszy błąd to próba zdefiniowania One2many bez istnienia pola Many2one po stronie dziecka — Odoo zgłosi błąd. Zawsze upewnij się, że inverse_name naprawdę istnieje.


Błędna składnia zapisu (write)

Aktualizując One2many przez kod lub API, trzeba stosować specjalne komendy Odoo (tuplowe) — nie można przypisać zwykłej listy Pythona. Prawidłowe polecenia to m.in.:


  • (0, 0, values_dict) — utworzenie nowego rekordu potomnego.
  • (1, child_id, values_dict) — aktualizacja istniejącego rekordu potomnego.
  • (2, child_id, 0) — usunięcie istniejącego rekordu potomnego.
  • (4, child_id, 0) — dodanie istniejącego rekordu do relacji.
  • (5, 0, 0) — odłączenie wszystkich rekordów potomnych od rodzica (bez kasowania ich).

Próba zapisania czegoś w rodzaju record.line_ids = [1, 2, 3] nie zadziała — trzeba użyć komend opisanych powyżej.


Mylące stosowanie One2many zamiast Many2many

Jeżeli potrzebujesz, by rekordy potomne były współdzielone między wieloma rodzicami, One2many nie jest właściwym wyborem — to pole wymusi jednoznaczne przypisanie i zmusi Cię do duplikowania danych. W takich przypadkach użyj Many2many.


Problemy wydajnościowe przy dużych listach podrzędnych

Wyświetlanie setek czy tysięcy wierszy w osadzonej tabeli znacząco spowalnia ładowanie formularza — typowy problem np. w fakturach czy ruchach magazynowych. Użyj ograniczeń (limit) w widoku listy lub przenieś listę do oddzielnego widoku.


Osierocone rekordy po usunięciu rodzica

Jeżeli usuniesz rodzica bez ustawienia ondelete='cascade' na polu Many2one dziecka, rekordy potomne mogą pozostać w bazie z pustym lub niepoprawnym wskaźnikiem. Z czasem to zaśmieca dane i prowadzi do błędów w raportach — zaplanuj politykę usuwania już na etapie projektowania modelu.

Podsumowanie


Pole One2many to fundament modelu danych Odoo — zasila kluczowe funkcje platformy: pozycje zamówień, linie faktur, zadania projektowe i wiele innych. Zrozumienie relacji One2many ↔ Many2one znacznie ułatwia czytanie i rozbudowę systemu.


Niezależnie czy konfigurujesz Odoo dla firmy, używasz Studio, czy tworzysz moduł od podstaw, One2many będzie jednym z częściej używanych narzędzi. Wiedza, kiedy go stosować i jak unikać błędów, oszczędzi czas i zabezpieczy integralność danych.

Jeżeli chcesz pogłębić wiedzę techniczną, przejrzyj pozostałe poradniki z kolekcji Odoo Data & API.

Potrzebujesz wsparcia przy wdrożeniu Odoo?


Dasolo pomaga firmom wdrażać, dostosowywać i optymalizować Odoo pod konkretne potrzeby biznesowe. Pomagamy projektować model danych, tworzyć moduły, konfigurować pola i zwiększać wartość już działających rozwiązań.

Masz pytania związane z projektem Odoo lub chcesz porozmawiać o optymalnej strukturze danych, skontaktuj się z nami— chętnie pomożemy.

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