مقدمة
قد لا يبدو حقل Binary مثيرًا، لكنه أحد اللبنات الأساسية في أي تركيب عملي لأودو. كل مرة يرفع فيها موظف عقدًا موقّعًا، يرفق مواصفات منتج، أو يضع شعار الشركة في بطاقة، يكون هناك حقل Binary يتصرّف كحافظة خلف الكواليس. فهم كيف يُخزَّن الملف، أين يُخزَّن فعليًا، ومتى يجب استخدام نوع حقول آخر يوفر عليك مشكلات الأداء أو حماية البيانات، يغيّر تجربة بناء النماذج وتوسيع النماذج في المشروع.
هذا الدليل يشرح بالأساس ما تخزّنه حقول Binary، كيف يؤثر وضع التخزين (attachment) على الأداء والمساحة، كيف تضيفه أو تزوّده عبر Odoo Studio أو كود بايثون، ومتى تستفيد منه عمليًا في موديولات مثل CRM وHR والمخازن والمحاسبة.
ما هو حقل الـ Binary في أودو
في طبقة ORM الخاصة بأودو، حقل Binary (fields.Binary) مخصّص لحفظ بيانات ثنائية: ملفات PDF، صور، مستندات أو أي مرفق يحمّله المستخدم على سجل. على واجهة المستخدم يظهر عادة كزر رفع/تنزيل بسيط داخل نموذج السجل، وبالضغط عليه يمكن للمستخدم تنزيل الملف المرفق مباشرة.
أهم نقطة تقنية يجب حفظها هي أين ينتهي الملف فعليًا. في إصدارات أودو الحديثة، الحقول تعمل بوضع المرفق (attachment) بشكل افتراضي، ما يعني أن البايتات تُخزّن في جدول ir.attachment وعلى نظام الملفات الخاص بالسيرفر، بينما عمود النموذج يحتوي على مرجع للإرفاق وليس الملف نفسه. هذا التصميم يحافظ على جداول قاعدة البيانات خفيفة ويسهّل إدارة الملفات على مستوى النظام.
داخل Odoo Studio ستجد الحقل معنونًا باسم File في قائمة الحقول. يعرض عنصر تحكم بسيط للرفع والتحميل داخل النماذج. أما للصور فهناك نوع مخصّص fields.Image يوفّر تغيير الحجم التلقائي ومعاينة مصغرة — سنذكر تفاصيله عند الحديث عن الصور.
في نموذج بايثون سيبدو تعريف حقل Binary ضمن النموذج على سبيل المثال كما يلي:
from odoo import fields, models
class ResPartner(models.Model):
_inherit = 'res.partner'
x_signed_contract = fields.Binary(
string='Signed Contract',
attachment=True,
)
x_signed_contract_filename = fields.Char(
string='Signed Contract Filename',
)
الممارسة الشائعة هي إضافة حقل Char مرافق للاحتفاظ باسم الملف الأصلي — عادة ينتهي الاسم بـ _filename. هذا الحقل يسمح للواجهة بعرض اسم الملف الصحيح عند التحميل أو التنزيل؛ بدونه سيحصل المستخدم على اسم عام وغير دال.
كيف يعمل الحقل
عند تعريف حقل Binary في موديل أودو، الإطار يتولّى إنشاء العمود في قاعدة البيانات عند تثبيت أو ترقية الوحدة تلقائيًا، فلا حاجة لكتابة SQL يدويًا.
أنماط التخزين
الوسيط attachment في تعريف الحقل يحدد مكان حفظ بايتات الملف بالفعل:
- attachment=True (مستحسن): يخزّن محتوى الملف في ir.attachment ويرتبط بالسجل عبر اسم الموديل ومعرّف السجل. عمود الموديل يحتوي على مرجع فقط. هذا يحافظ على صغر حجم جداول النموذج ويستفيد من نظام تخزين الملفات الخاص بأودو.
- attachment=False: تُخزّن البيانات المشفّرة بقاعدة64 مباشرة داخل عمود جدول الموديل. هذا يؤدي لنمو كبير في حجم الصفوف وإبطاء الاستعلامات على ذلك الموديل. تجنّب هذا الوضع لأي ملف يتجاوز حجم صورة مصغّرة صغيرة.
صيغة البيانات
حقول Binary تتعامل مع البيانات بصيغة base64. عند القراءة عبر ORM أو XML-RPC تحصل على سلسلة Base64، وعند الكتابة يجب أن تزود الحقل بقيمة Base64 أيضاً.
عمليًا هذا يعني تشفير قبل الكتابة وفك التشفير عند القراءة:
import base64
# Writing a file to a Binary field
with open('document.pdf', 'rb') as f:
encoded = base64.b64encode(f.read()).decode('utf-8')
record.write({'x_signed_contract': encoded})
# Reading a file from a Binary field
raw_bytes = base64.b64decode(record.x_signed_contract)
السمات الأساسية للحقل
هذه أهم الإعدادات التي قد تضبطها على حقل Binary داخل إطار أودو:
- attachment: بوليان يحدّد إن كان التخزين في ir.attachment (True) أو مباشرة في العمود (False). الافتراضي: True في الإصدارات الحديثة.
- string: تسمية العرض التي تظهر في الواجهة.
- required: يجعل الحقل إجباريًا قبل حفظ السجل.
- compute: يربط دالة بايثون لحساب قيمة الحقل ديناميكيًا، مثل توليد PDF عند الطلب.
- store: عند استخدامها مع compute تحفظ القيمة المحسوبة في قاعدة البيانات.
- groups: تقيد الوصول للحقل لمجموعات مستخدمين محددة — مهم للوثائق الحساسة.
- copy: يحدّد إن كانت القيمة تُنسخ عند تكرار السجل؛ السلوك يختلف اعتمادًا على وضع attachment وإصدار أودو.
النسخة المخصّصة للصور fields.Image
fields.Image هو نوع مشتق من fields.Binary ظهر في أودو 13، يوفّر تغيير حجم تلقائي إلى أبعاد قصوى يمكن ضبطها، وحجم معاينة مصغّرة، ويعرض صورة مسبقًا داخل النماذج. للصور مثل صور المنتجات، صور الموظفين أو شعارات الشركات، استخدم fields.Image بدلاً من Binary العادي لمنع رفع ملفات ضخمة ولتحسين تجربة المستخدم.
كيف يظهر في الواجهات
في نماذج العرض، الودجت الافتراضي لحقل Binary هو زر رفع/تحميل. للصور طبّق ودجت image لتحصل على معاينة مصغّرة. في قوائم العرض (list views) لا يُنصح بعرض محتوى Binary الكامل لأن ذلك يجلب بيانات كبيرة لكل صف مرئي؛ الحل الشائع عرض أيقونة أو حقل منطقي يُشير لوجود مرفق بدل تحميل الملف لكل صف.
حالات استخدام عملية
حقل Binary يظهر في الكثير من موديولات أودو. فيما يلي أمثلة عملية شائعة في سير العمل اليومي.
CRM: حفظ اتفاقيات عدم الإفشاء أو العقود الموقعة على بطاقات العملاء
فرق المبيعات تستفيد من إمكانية إرفاق عقود أو اتفاقيات مباشرة على بطاقة العميل أو الفرصة. وجود الحافظة المرفقة على السجل يبقي المستندات في نفس مكان سير العمل، يسرّع الوصول ويقلّل الاعتماد على أدوات خارجية لإدارة المستندات في حالات الاستخدام البسيطة.
الموارد البشرية: حفظ مستندات الموظفين
إدارات الموارد البشرية تحتاج عادة لحفظ نسخ من هويات الموظف، تصاريح العمل، عقود التوظيف الموقعة، أو شهادات التدريب. وضع الحقول على نموذج hr.employee يسمح بالتحكم في من يرى هذه الملفات عبر خاصية groups، وبالتالي حماية الخصوصية مع إبقاء المستندات متاحة للمتصدّرين المحددين.
المخازن: مواصفات المنتج وبيانات السلامة
المنتجات التقنية غالبًا ترافقها أوراق مواصفات أو بطاقات بيانات السلامة. إضافة حقل Binary على product.template يمنح فرق المشتريات والمستودع وصولًا سريعًا للمستندات الفنية مباشرة من بطاقة المنتج — تعديل شائع في شركات الصناعة والتوزيع وسهل التنفيذ عبر Studio أو وحدة مخصّصة.
المبيعات: ختم الشركة أو توقيع مفوّض للطباعة
بعض الشركات تحتاج تضمين ختم الشركة أو صورة توقيع مفوّض في العروض أو أوامر البيع المطبوعة. تخزين هذا الأصل البصري في حقل fields.Image على res.company ويسمح بإدراجه تلقائيًا في تقارير QWeb، ما يوفّر الوقت ويقلّل الأخطاء اليدوية في المطبوعات.
المحاسبة: إرفاق إيصالات ممسوحة ضوئيًا على مصاريف الموظفين
سير عمل المصروفات يتطلب غالبًا إرفاق إيصال أو فاتورة كسند للمصروف. بينما نظام المرفقات الافتراضي في أودو يغطي الكثير من الحالات، في نماذج مخصصة أو تكاملات خارجية يمكن لحقل Binary أن يخزن إيصالًا أو PDF مباشرًا على السجل ويُشمل في منطق الموافقات.
إنشاء أو تخصيص حقل Binary
هناك ثلاث طرق رئيسية لإضافة حقل Binary إلى موديل أودو، بحسب حاجتك الفنية ومدى رغبتك في التحكم.
باستخدام Odoo Studio (بدون كود)
Odoo Studio أداة منخفضة الكود مدمجة. لإضافة حقل Binary بدون برمجة:
- افتح Odoo Studio من القائمة الرئيسية.
- انتقل إلى النموذج الذي تريد إضافة الحقل إليه.
- اسحب حقل File من اختيار الحقول إلى داخل النموذج.
- عدّل التسمية وشروط الظهور في لوحة الخصائص.
- احفظ وأغلق Studio.
سيُنشأ الحقل باسم مسبوق بـ x_studio_ ويستخدم وضع attachment تلقائيًا. لا حاجة لتعديلات قاعدة بيانات يدوية، ومناسب لمديري الأعمال الذين يحتاجون رفع ملفات سريعًا دون مطور.
باستخدام بايثون في وحدة مخصّصة
للتخصيصات التي يجب وضعها تحت تحكم إصدار ونشر عبر بيئات متعددة، الطريقة القياسية تعريف الحقول في بايثون داخل وحدة مخصّصة. هذه الممارسة موصى بها لأي تخصيص محترف لأودو:
from odoo import fields, models
class HrEmployee(models.Model):
_inherit = 'hr.employee'
x_id_document = fields.Binary(
string='ID Document',
attachment=True,
groups='hr.group_hr_user',
)
x_id_document_filename = fields.Char(
string='ID Document Filename',
)
بعد تعريف الحقل تضيفه إلى عرض النموذج في XML مع widget='binary' وattribute filename تشير لحقل Char المرافق. أودو يتولى تعديل قاعدة البيانات عند تثبيت الوحدة، وتعمل هذه الطريقة بسلاسة على منصات نشر متنوعة مثل Odoo.sh أو استضافة محلية.
باستخدام واجهة XML-RPC
إذا كنت تدار إعدادات أودو برمجيًا عبر سكربت نشر أو دفاتر تشغيل تلقائية، يمكنك إنشاء حقول Binary عبر API الخاص بـ XML-RPC:
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_custom_document',
'field_description': 'Custom Document',
'model_id': model_id,
'ttype': 'binary',
'state': 'manual',
}]
)
القيمة state: 'manual' تشير أن الحقل انشئ يدويًا وليست جزءًا من وحدة. الحقول المنشأة عبر الـ API تستخدم وضع attachment افتراضيًا في الإصدارات الحالية، وهذه طريقة مفيدة في سيناريوهات التهيئة التلقائية.
أفضل الممارسات
1. استخدم attachment=True دائمًا
إلا إذا كان لديك سبب تقني واضح لتخزين البايتات داخل عمود الجدول، استخدم وضع attachment. يحافظ هذا على جداول النموذج صغيرة ويمنع تباطؤ الاستعلامات، كما أن هذا الوضع هو الافتراضي في الإصدارات الحديثة — لذلك غالبًا يجوز ترك الخاصية دون ضبط. لأي ملف أكبر من صورة مصغّرة، attachment لازم.
2. أضف حقل اسم الملف المرافق
أضف دائمًا حقل Char باسم ينتهي بـ _filename إلى جانب أي Binary يظهر في واجهة المستخدم. بدون هذا الحقل سيحصل المستخدمون على أسماء تنزيل عامة وغير مفيدة. هذه الإضافة بسيطة لكنها تحسّن تجربة المستخدم بشكل ملحوظ.
3. استخدم fields.Image للمحتوى البصري
لصور المنتجات أو صور الأشخاص أو الشعارات، استخدم fields.Image بدل Binary العادي. يحدّد الحجم تلقائيًا ويعطي معاينات مصغرة ويحمي من رفع ملفات ضخمة. اختيار نوع الحقل المناسب جزء أساسي من تصميم موديل نظيف.
4. قيّد الوصول باستخدام groups
الوثائق الحساسة مثل ملفات الموظفين أو العقود الموقعة يجب أن تُقيّد عبر groups حتى لا يتاح الاطلاع إلى غير المخوّلين. هذا مهم للخصوصية ومتطلبات التدقيق في بيئات منظمة.
5. تعامل مع التشفير Base64 بعناية في الكود
عند قراءة أو كتابة الحقول برمجيًا تعامل دائمًا مع الترميز صراحةً: استخدم base64.b64encode(file_bytes).decode('utf-8') قبل الكتابة، وbase64.b64decode(value) بعد القراءة. الافتراض أن البيانات بالفعل في الشكل المطلوب يؤدي لأخطاء تظهر عند التعامل مع ملفات حقيقية.
الأخطاء الشائعة
مخاطر تعيين attachment=False للملفات الكبيرة
تخزين الملفات داخل عمود قاعدة البيانات يمكن أن يضخم جداول PostgreSQL بسرعة. عدد قليل من ملفات PDF المخزّنة بهذه الطريقة قد يضيف مئات الميجابايت على جدول واحد، مما يبطئ كل الاستعلامات عليه. هذه من أكثر الأخطاء تأثيرًا عند إدارة قواعد بيانات أودو؛ تصحيحها يتطلب سكربت ترحيل وعملية تخطيط دقيقة.
نسيان حقل اسم الملف المرافق
دون حقل Char للاسم، المستخدمون يحصلون على أسماء تنزيل عامة، ما يعطي انطباعًا بأن التنفيذ ناقص. إضافة هذا الحقل بسيطة وتُعد جزءًا من تعريف الحقل عندما يظهر في واجهة المستخدم.
خلط بين Binary وImage
استخدام Binary عادي للصور يحرمك من ميزات تغيير الحجم والمعاينات التي يوفرها fields.Image، وقد يؤدي لرفع صور كبيرة تُبطئ تحميل النماذج. بالمقابل استخدام fields.Image لملفات غير صور (مثل PDF) يتسبب بأخطاء لأن النظام يحاول معالجتها كصور. القاعدة: طابق نوع الحقل بنوع المحتوى المتوقع.
إظهار حقول Binary مباشرة في قوائم العرض
وضع Binary في list view يجعل أودو يجلب محتوى الملف الكامل لكل صف مرئي؛ لقائمة بها خمسين صفًا قد تُنقل ميغابايتات من البيانات فقط لعرض الصفحة. إذا كنت تحتاج إظهار وجود ملف في القائمة، استخدم حقل منطقي محسوب أو أيقونة بدل تحميل الملف لكل صف.
عدم التحقق من False قبل المعالجة في الكود
حقل Binary بدون قيمة يرجع False في بايثون وليس سلسلة فارغة. إن حاولت فك تشفير False ستحصل على TypeError. احمِ كودك دائمًا بشرط: if record.x_document: data = base64.b64decode(record.x_document). هذا مهم في compute methods، Server Actions، وأي مكان يعالج القيم بشرط وجودها.
الخلاصة
حقل Binary بسيط لكنه مهم في موديل بيانات أودو. هو المسؤول عن تخزين الملفات بشكل يتكامل مع واجهة المستخدم، نظام المرفقات، وآليات التحكم في الوصول.
السلوكيات التي تضمن نجاح التنفيذ: استخدام وضع attachment دومًا، إضافة حقل اسم الملف المرافق، اختيار fields.Image للمحتوى البصري، تقييد الوصول للمستندات الحساسة، ومعالجة base64 بعناية في الكود. هذه الممارسات تمنع المشكلات الشائعة قبل أن تظهر في بيئة الإنتاج.
سواء أضفت حقل رفع ملفات عبر Odoo Studio، صممت وحدة بايثون مخصصة، أو أنشأت الحقول عبر ORM أو XML-RPC، البدء الصحيح مع حقول Binary يؤدي إلى تركيب أودو أنظف وأكثر اعتمادية على المدى الطويل.
في Dasolo نساعد الشركات على تنفيذ، تخصيص، وتحسين أودو عبر الأقسام كلها. إذا احتجت تصميم موديل بيانات مناسب، بناء سير عمل لإدارة الملفات، أو تطوير وحدة أودو كاملة، فريقنا جاهز لدعمك. تواصل معنا ولنتحدث عن مشروع أودو الخاص بك.