مقدمة
في معظم حالات التطوير على أودو، يستخدم المطورون حقل Many2one لتوصيل سجل بسجل آخر لأنّه حل بسيط ومباشر. لكن هناك مواقف تتطلب مرونة أكبر: نفس الحقل قد يحتاج أن يشير إلى فاتورة في مناسبة، وإلى أمر شراء في مناسبة أخرى، أو إلى مهمة مشروع في حالة ثالثة. هذه الحاجة إلى مرجعية متعددة الأهداف هي بالضبط ما صُمّم له حقل Reference.
حقل Reference هو نوع بيانات مرن داخل ORM الخاص بأودو: بدلاً من ربط الحقل بنموذج واحد ثابت، يتيح لك تحديد مجموعة من النماذج المسموح بها، ثم يترك للمستخدم اختيار نوع المستند ومن ثم السجل المحدد داخل ذلك النموذج. الناتج هو رابط متعدد الأشكال يمكن أن يخدم سيناريوهات عمل مختلفة دون إنشاء حقول متعددة.
هذا الدليل يشرح ما الذي يخزّنه الحقل، كيف يتصرف داخل بنية بيانات أودو، كيف تضيفه وتعدّله سواء عبر واجهة Studio أو عبر بايثون، ومتى يكون استخدامه فعلاً منطقيّاً في سير العمل التجاري.
ما هو حقل Reference في أودو؟
بصفة عامة، حقل Reference يخزن رابطاً إلى سجل من أي نموذج مدرج في لائحة selection الخاصة به، وهذا يجعله مختلفاً جوهرياً عن Many2one الذي يشير دائماً إلى نموذج واحد محدد.
من الناحية التقنية، القيمة في قاعدة البيانات تُحفظ كنص بصيغة model_name,record_id. مثلاً إشارة إلى أمر بيع برقم 42 تُحفظ كـ sale.order,42. معرفة هذا الأمر ضرورية عند إجراء استعلامات أو تصفية مباشرة على الجدول.
في واجهة المستخدم يظهر الحقل كمدخل بمرحلتين: يختار المستخدم أولاً نوع المستند من قائمة منسدلة (مثل: أمر بيع، فاتورة، مهمة مشروع)، ثم يبحث ويختار السجل المطابق لذلك النوع. بعد تعلّم الخطوتين تصبح الواجهة بسيطة وواضحة.
فيما يلي مثال مختصر لتعريف حقل Reference في كود بايثون:
from odoo import fields, models
class HelpDeskTicket(models.Model):
_inherit = 'helpdesk.ticket'
related_document = fields.Reference(
selection=[
('sale.order', 'Sale Order'),
('purchase.order', 'Purchase Order'),
('account.move', 'Invoice'),
('project.task', 'Project Task'),
],
string='Related Document',
)
قيمة selection هي قائمة من ثنائيات: الاسم التقني للنموذج (مثل sale.order) والنص الذي سيشاهده المستخدمون في القائمة. أنت من يحدّد النماذج المتاحة للربط.
يمكن أيضاً جعل هذه اللائحة ديناميكية عبر إرجاعها من دالة تقرأ نماذج مُسجلة في ir.model، وهي طريقة مناسبة لأدوات قابلة للتخصيص بدرجة عالية، لكن يجب تصفية النتائج كي لا تربك المستخدم.
في Odoo Studio، ستجد نوع الحقل باسم Reference ضمن لوحة الحقول. عند إضافته من Studio يمكنك تحديد النماذج القابلة للاختيار مباشرة من الواجهة دون كتابة كود، مما يجعله خياراً مناسباً للتخصيصات السريعة.
كيف يعمل الحقل
فهم كيف يخزن الحقل بياناته وكيف يسترجعها يساعدك على استخدامه بشكل صحيح وتجنب مفاجآت عند تطوير أو صيانة النظام.
التخزين في قاعدة البيانات
على عكس Many2one الذي يخزن معرفاً صحيحاً فقط، حقل Reference يخزن سلسلة نصية تحتوي اسم النموذج ومعرف السجل مثل sale.order,15 في عمود VARCHAR داخل بوستجري إس كيو إل. هذا التصميم يقطع الطريق أمام قيود المفتاح الأجنبي التقليدية لتمكين العلاقات متعددة الأشكال.
وبما أن العمود ليس مفتاحاً أجنبياً فعلياً، فلن تقوم قاعدة البيانات بتنظيف القيم عند حذف السجل المشار إليه. إذا تم حذف أمر بيع، سيبقى في الحقل النص القديم ما لم تتدخل آلية تنظيف، وهذه النقطة مهمة عند تصميم منطق تكامل البيانات.
الوصول إلى السجل المرتبط في بايثون
عند قراءة قيمة Reference في بايثون، يقوم أودو بتحويل النص إلى كائن السجل الخاص بالنموذج المشار إليه. يمكنك الوصول إلى حقوله كما تفعل مع Many2one. وإذا كان الحقل فارغاً يعيد False.
ticket = self.env['helpdesk.ticket'].browse(1)
doc = ticket.related_document
if doc:
print(doc._name) # e.g. 'sale.order'
print(doc.name) # e.g. 'S00042'
print(doc.id) # e.g. 15
هذه طبقة تجريد مفيدة: رغم أن التخزين نصي، يُعيد الإطار كائناً عملياً عند الاستعلام في الكود، مما يسهل التعامل معه.
السمات الأساسية للحقل
إليك أهم الخيارات التي يمكنك ضبطها لحقل Reference داخل إطار عمل أودو:
- selection: لائحة النماذج القابلة للاختيار. يمكن أن تكون ثابتة أو مرجعية إلى دالة تُرجع القائمة بشكل ديناميكي.
- string: تسمية الحقل الظاهرة في واجهة المستخدم.
- required: يجعل الحقل إلزامياً؛ يجب اختيار نوع وسجل قبل الحفظ.
- readonly: يمنع تعديل القيمة من الواجهة، مفيد إن كانت القيمة تُحْدَد برمجياً.
- help: شرح يظهر عند تحريك المؤشر فوق التسمية، مفيد لتوجيه المستخدم.
- compute: يمكن أن يكون الحقل محسوباً عبر دالة بايثون، ما يسمح بتعيين المرجع تلقائياً وفق منطق تجاري.
التصفية والبحث
بما أن القيمة مخزنة كسلسلة نصية، فعمليات البحث تحتاج إلى بناء سلسلة المطابقة تماماً في شروط الدومين.
مثال للبحث عن تذاكر مرتبطة بأمر بيع محدد:
tickets = self.env['helpdesk.ticket'].search([
('related_document', '=', 'sale.order,15')
])
ويمكن أيضاً البحث حسب نوع النموذج باستخدام عامل like:
tickets = self.env['helpdesk.ticket'].search([
('related_document', 'like', 'sale.order,')
])
حالات استخدام عملية
ضع في الحسبان هذا السلوك النصي عند تصميم تقارير أو حقول محسوبة تعتمد على قيم Reference لأنها تختلف عن تصفية Many2one الاعتيادية.
قيمة الحقل تتجلى في أماكن يكون فيها الربط السياقي الواحد قابل أن يشير إلى أنواع مستندات مختلفة. فيما يلي أمثلة تطبيقية من واقع الأعمال.
1. تذاكر دعم مرتبطة بأي مستند
فريق الدعم يتعامل أحياناً مع قضايا مرتبطة بفاتورة أو أمر تسليم أو عقد أو منتج تالف. بدلاً من وجود حقل لكل نوع مستند، يكفي حقل Reference واحد على نموذج التذكرة يسمح للوكيل باختيار النوع ثم السجل، فيحصل كل سجل تذكرة على مرجع واحد يجمع كل السياق.
2. أنشطة مبيعات تربط مصادر متعددة
مهمة متابعة مبيعات قد تنبع من فرصة، عرض سعر، عقد قائم أو قضية دعم. وجود حقل Reference في نموذج النشاط يتيح وضع مرجع أصلي متغير دون قصر النشاط على نموذج واحد.
3. ملاحظات عامة عبر وحدات متعددة
شركات كثيرة تنشئ نموذج ملاحظات داخلي لتسجيل ملاحظات عامة يمكن ربطها بأي سند: عميل، مهمة مشروع، أمر تصنيع أو أمر شراء. حقل Reference يجنّبك تكرار نموذج الملاحظة لكل كيان.
4. تدفق الموافقات لمستندات متنوّعة
نظام موافقات عام يحتاج أن يشير إلى أي نوع مستند قيد الموافقة: أمر شراء، مصروف، إجازة أو عقد. وضع Reference في نموذج الموافقة يبسط البنية بحيث تغطي نفس منطق الموافقات جميع الأنواع دون تكاثر نماذج.
5. مصاريف مرتبطة بمشروعات أو أوامر بيع
إنشاء أو تخصيص حقل Reference
في المحاسبة قد تحتاج المصاريف أن تُربط بمشروع أو بأمر بيع حسب نوع التكلفة. حقل Reference يضيف المرونة للمحاسب لربط الإيصال بالمستند المناسب—وهو حل شائع في شركات الخدمات والاستشارات.
هناك طريقتان رئيسيتان لإضافة حقل Reference لنموذج: عبر Odoo Studio للنهج بدون كود، أو مباشرة بالبايثون للتحكم الكامل.
باستخدام Odoo Studio
في Studio يمكنك إضافة الحقل من لوحة الحقول واختيار نوع Reference وتحديد النماذج المسموح بها من الواجهة. الحقول التي ينشئها Studio تُخزن كحقول مخصصة تبدأ عادةً بـ x_، وتعد طريقة سريعة وغير تقنية لإجراء تخصيصات بسيطة—مع بعض القيود على الخيارات المتقدمة مثل دوال الاختيار الديناميكية.
التنفيذ التقني عبر بايثون
لإنشاء الحقل كجزء من وحدة تطوير، عرّفه في ملف الموديل بالبايثون. المثال التالي يوضح استخدام دالة لتوليد لائحة الاختيارات ديناميكياً:
from odoo import api, fields, models
class ApprovalRequest(models.Model):
_name = 'approval.request'
_description = 'Approval Request'
name = fields.Char(string='Request Name', required=True)
@api.model
def _get_document_types(self):
return [
('purchase.order', 'Purchase Order'),
('hr.expense.sheet', 'Expense Report'),
('hr.leave', 'Time Off Request'),
('sale.order', 'Sale Order'),
]
document_ref = fields.Reference(
selection='_get_document_types',
string='Document',
help='Select the document this approval relates to.',
)
استخدام دالة لإرجاع selection يمنحك مرونة: يمكنك تضمين شروط، فحص ما إذا كانت وحدات معينة مُثبتة، أو توليد القائمة من سجلات تهيئة.
إنشاء الحقل عبر XML-RPC API
يمكنك أيضاً إنشاء حقل Reference برمجياً عبر واجهة XML-RPC، مفيد عند نشر إعدادات عن بُعد أو كجزء من سكربت إعداد. نوع الحقل في هذه الحالة هو reference وتُمرّر قيمة selection كسلسلة قابلة للتقييم.
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_related_document',
'field_description': 'Related Document',
'model_id': model_id,
'ttype': 'reference',
'selection': "[('sale.order', 'Sale Order'), ('purchase.order', 'Purchase Order')]",
'state': 'manual',
}]
)
لاحظ أنه عند الإنشاء عبر API تُمرّر اللائحة كسلسلة نصية قابلة للتقييم لأن هذا هو الشكل الذي يخزّن فيه أودو القيمة في جدول ir.model.fields.
ممارسات موصى بها
إرشادات عملية عند العمل مع حقل Reference
- حافظ على لائحة الاختيارات مختصرة ومركزّة: لا تضف كل النماذج المتاحة لمجرّد الإمكانية. لائحة طويلة تربك المستخدم وتزيد احتمال اختيار خاطئ.
- استخدم Many2one إن كان الربط ثابتاً: إن كان الحقل سيشير دوماً لنفس النموذج، فـ Many2one أبسط وأسهل في الاستعلام والتقارير.
- تحقق دوماً من القيم الفارغة في الحقول المحسوبة: Reference الفارغ يعيد False في بايثون، لذا أمنع الأخطاء بالتحقق قبل الوصول إلى السجل المرتبط.
- عالج المراجع اليتيمة عبر إجراءات مجدولة: لأن قاعدة البيانات لا تفرض تكامل مرجعي، من الأفضل إنشاء إجراء أو مهمة مجدولة تمسح أو تبلغ عن المراجع التي تشير إلى سجلات محذوفة.
- استخدم تسميات وصفية في لائحة الاختيارات: اجعل ما يراه المستخدم نصّاً تجارياً مفهومًا مثل "فاتورة عميل" بدلاً من أسماء نماذج تقنية.
- وثّق سبب اختيار Reference في المواصفات التقنية: المطوّرون القادمون بعدك سيقدّرون توضيح لماذا اخترت علاقة متعددة الأشكال وما النماذج المرتبطة بها.
المشكلات الشائعة
أخطاء شائعة يجب الانتباه لها
التعامل معها كأنها Many2one في شروط الدومين
بعض المطورين يكتبون شروط بحث كما لو كانت Many2one—مثلاً [('document_ref', '=', 15)]—وهذا خطأ لأن القيمة المخزنة سلسلة مثل sale.order,15. يجب بناء السلسلة كاملة عند إنشاء شروط البحث.
نسيان أن الحذف يترك قيم يتيمة
حذف السجل المشار إليه لا يزيل النص في حقل Reference. في هذه الحالة عند القراءة سيُعيد الحقل False بدلاً من ربط صالح، لذا يجب أن يتعامل الكود مع سيناريو السجل المفقود.
الإفراط في اختيار جميع النماذج ديناميكياً
إرجاع كل النماذج من ir.model يجعل القائمة ضخمة ومربكة للمستخدم. عادة ما يكون من الأفضل تقييد الخيارات لمجموعة مدروسة من أنواع المستندات.
التوقع بأن التجميع في التقارير يعمل طبيعياً
لأن القيمة مخزنة كنص، وظائف التجميع والـ group-by الافتراضية قد لا تعمل كما في Many2one. إن احتجت تجميعاً حسب نوع المستند، ففكّر في حقل محسوب يفصل اسم النموذج أو حقل اختيار منفصل يمكن استخدامه في التقارير.
خلط Reference مع Many2one في Studio
بعض مستخدمي Studio يخلطون بين الحقلين لأن كلاهما يربط بسجل آخر. تذكر أن Many2one يحدد النموذج عند الإنشاء بينما Reference يتيح للمستخدم اختيار النموذج لكل سجل على حدة. إذا أنشأت Many2one بالخطأ عندما كنت تحتاج Reference فسيتطلب الأمر إعادة بناء الحقل.
خلاصة
الخلاصة: متى تستخدم Reference؟
حقل Reference يعالج فجوة لا يستطيع Many2one ملؤها، خصوصاً عندما يحتاج الربط أن يكون مرناً ليشير إلى أنواع مستندات مختلفة حسب السياق. الحقل سهل التعريف، متاح في Studio للتخصيصات بدون كود، ويمكن دمجه بسلاسة في نماذج بايثون للتطبيقات التقنية.
تذكّر النقاط الأساسية: التخزين كسلسلة نصية، غياب التنظيف التلقائي عند حذف السجلات، والحاجة لاستخدام سلاسل مركبة عند التصفية بدلاً من أرقام معرّفة فقط. بعد استيعاب هذه الاختلافات يتصرف الحقل بشكل متوقع ويمكن الاعتماد عليه لتصميم نماذج مرنة ومنظّمة.
تحتاج مساعدة في تنفيذ أودو؟
سواء كنت تبني سير موافقات عام، تربط تذاكر دعم بأنواع مستندات مختلفة، أو تصمّم نظام ملاحظات يغطي وحدات متعددة، حقل Reference يوفر حلّاً واضحاً وقابلاً للصيانة دون تكرار المنطق نفسه عبر نماذج متعددة.
في Dasolo نساعد الشركات على تنفيذ وتخصيص وتحسين أودو وفق سياق أعمالهم الحقيقي. نغطي كل شيء من بناء منطق حقول مخصص وتصميم نموذج بيانات من الصفر إلى توسيع بيئات أودو موجودة بميزات جديدة وبأفضل الممارسات التقنية.