اقدامات¶
اکشنها رفتار سیستم را در پاسخ به اقدامات کاربر تعریف میکنند: ورود به سیستم، دکمهٔ اکشن، انتخاب یک فاکتور، ...
اکشنها میتوانند در پایگاهداده ذخیره شوند یا مستقیماً بهصورت دیکشنری در، برای مثال، متدهای button بازگردانده شوند. همهٔ اکشنها دو ویژگی الزامی مشترک دارند:
typeدستهٔ اکشن فعلی؛ تعیین میکند چه فیلدهایی ممکن است استفاده شوند و اکشن چگونه تفسیر شود
nameتوضیح کوتاه و قابلخواندن توسط کاربر برای اکشن؛ ممکن است در رابط کاربری کلاینت نمایش داده شود
یک کلاینت میتواند اکشنها را در ۴ فرم دریافت کند:
Falseاگر هر دیالوگ اکشنی در حال حاضر باز است، آن را ببندید
- یک رشته
اگر یک client action مطابقت داشته باشد، بهعنوان tag اکشن کلاینت تفسیر شود، در غیر این صورت بهعنوان یک عدد در نظر گرفته شود
- یک عدد
رکورد اکشن متناظر را از پایگاهداده میخواند؛ ممکن است یک شناسهٔ پایگاهداده یا یک external id باشد
- یک دیکشنری
بهعنوان توصیفگر (descriptor) اکشن کلاینت در نظر گرفته شود و اجرا گردد
بایندینگها¶
علاوه بر دو ویژگی الزامی، همهٔ اکشنها ویژگیهای اختیاری مشترکی نیز دارند که برای نمایش یک اکشن در منوی متنی (contextual menu) یک مدل دلخواه استفاده میشوند:
binding_model_idمشخص میکند که اکشن به کدام مدل bind شده است
توجه
برای Server Actions، از
model_idاستفاده کنید.binding_typeنوع binding را مشخص میکند، که اساساً تعیین میکند اکشن زیر کدام منوی متنی ظاهر شود
action(پیشفرض)مشخص میکند که اکشن در منوی متنی مدل bindشده ظاهر خواهد شد.
reportمشخص میکند که اکشن در منوی متنی مدل bindشده ظاهر خواهد شد.
binding_view_typesفهرستی از انواع نما، جداشده با ویرگول، که اکشن برای آنها در منوی متنی ظاهر میشود، اساساً "list" و/یا "form". مقدار پیشفرض
list,formاست (هم list و هم form)
اکشنهای پنجره (ir.actions.act_window)¶
رایجترین نوع اکشن، که برای نمایش بصری یک مدل از طریق views استفاده میشود: یک window action مجموعهای از انواع نما (و احتمالاً نماهای خاص) را برای یک مدل (و احتمالاً رکورد خاصی از مدل) تعریف میکند.
فیلدهای آن عبارتاند از:
res_modelمدلی که نماها برای آن نمایش داده میشوند
viewsفهرستی از جفتهای
(view_id, view_type). عنصر دوم هر جفت دستهٔ نما است (list، form، graph و غیره) و عنصر اول یک شناسهٔ پایگاهداده اختیاری است (یاFalse). اگر هیچ شناسهای ارائه نشده باشد، کلاینت باید نمای پیشفرض نوع مشخصشده را برای مدل درخواستشده دریافت کند (این کار بهصورت خودکار توسطfields_view_get()انجام میشود). نوع اول در فهرست، نوع نمای پیشفرض است و هنگام اجرای action بهصورت پیشفرض باز میشود. هر نوع نما باید حداکثر یک بار در فهرست حضور داشته باشدres_id(اختیاری)اگر نمای پیشفرض
formباشد، رکوردی را که باید بارگذاری شود مشخص میکند (در غیر این صورت باید رکورد جدیدی ایجاد شود)search_view_id(اختیاری)جفت
(id, name)؛idشناسهٔ پایگاهدادهٔ یک نمای جستجوی خاص برای بارگذاری برای این action است. بهصورت پیشفرض نمای جستجوی پیشفرض مدل دریافت میشودtarget(اختیاری)اینکه نماها باید در ناحیهٔ محتوای اصلی (
current)، در حالت تمامصفحه (fullscreen) یا در یک پنجرهٔ بازشو (new) باز شوند. برای پاک کردن مسیر راهبری، ازmainبه جایcurrentاستفاده کنید. بهصورت پیشفرضcurrent.context(اختیاری)دادههای context اضافی برای ارسال به نماها
domain(اختیاری)دامنهٔ فیلترسازی که بهصورت ضمنی به همهٔ کوئریهای جستجوی نماها افزوده میشود
limit(اختیاری)تعداد رکوردهایی که بهصورت پیشفرض در فهرستها نمایش داده میشوند. بهصورت پیشفرض ۸۰ در وبکلاینت
برای مثال، برای باز کردن مشتریان (شریک با پرچم customer تنظیمشده) با نماهای فهرست و فرم:
{
"type": "ir.actions.act_window",
"res_model": "res.partner",
"views": [[False, "list"], [False, "form"]],
"domain": [["customer", "=", true]],
}
یا برای باز کردن نمای فرم یک محصول مشخص (بهصورت جداگانه دریافتشده) در یک پنجرهٔ بازشوی جدید:
{
"type": "ir.actions.act_window",
"res_model": "product.product",
"views": [[False, "form"]],
"res_id": a_product_id,
"target": "new",
}
اکشنهای پنجرهای موجود در پایگاهداده چند فیلد متفاوت دارند که باید توسط کلاینتها نادیده گرفته شوند و بیشتر برای ترکیب فهرست views استفاده میشوند:
view_mode(پیشفرض=list,form)فهرست انواع نماها بهصورت رشتهای جداشده با کاما (/!\ بدون فاصله /!\). همهٔ این انواع در فهرست
viewsتولیدشده حضور خواهند داشت (حداقل با view_id برابرFalse)view_idsM2M1 به اشیای نما، محتوای اولیهٔ
viewsرا تعریف میکندتوجه
نماهای Act_window را میتوان بهصورت تمیز از طریق
ir.actions.act_window.viewنیز تعریف کرد.اگر قصد دارید چندین نما برای مدل خود مجاز کنید، استفاده از ir.actions.act_window.view به جای
view_idsدر action ترجیح داده میشود<record model="ir.actions.act_window.view" id="test_action_tree"> <field name="sequence" eval="1"/> <field name="view_mode">list</field> <field name="view_id" ref="view_test_tree"/> <field name="act_window_id" ref="test_action"/> </record>
view_idنمای خاصی که به فهرست
viewsاضافه میشود در صورتی که نوع آن بخشی از فهرستview_modeباشد و توسط یکی از نماهایview_idsپر نشده باشد
اینها بیشتر هنگام تعریف اکشنها از Data Files استفاده میشوند:
<record model="ir.actions.act_window" id="test_action">
<field name="name">A Test Action</field>
<field name="res_model">some.model</field>
<field name="view_mode">graph</field>
<field name="view_id" ref="my_specific_view"/>
</record>
از نمای "my_specific_view" استفاده خواهد کرد حتی اگر آن نما، نمای پیشفرض مدل نباشد.
ترکیب سمت سرور دنبالهٔ views به شرح زیر است:
هر
(id, type)را ازview_ids(مرتبشده بر اساسsequence) دریافت کنیداگر
view_idتعریف شده باشد و نوع آن قبلاً پر نشده باشد،(id, type)آن را اضافه کنیدبرای هر نوع پرنشده در
view_mode،(False, type)را اضافه کنید
- 1
از نظر فنی M2M نیست: یک فیلد sequence اضافه میکند و ممکن است فقط از یک نوع نما بدون شناسهٔ نما تشکیل شود.
اکشنهای URL (ir.actions.act_url)¶
اجازهٔ باز کردن یک URL (وبسایت/صفحهٔ وب) را از طریق یک action در Odoo میدهد. میتواند از طریق دو فیلد سفارشیسازی شود:
urlآدرسی که هنگام فعالسازی action باز میشود
target(پیشفرض=new)مقادیر در دسترس عبارتاند از:
new: URL را در پنجره/صفحهٔ جدید باز میکندself: URL را در پنجره/صفحهٔ جاری باز میکند (محتوای فعلی را جایگزین میکند)download: به URL دانلود تغییر مسیر میدهد
مثال:
{
"type": "ir.actions.act_url",
"url": "https://odoo.com",
"target": "self",
}
این کار بخش محتوای جاری را با صفحهٔ اصلی Odoo جایگزین میکند.
اکشنهای سرور (ir.actions.server)¶
اجازهٔ راهاندازی کد پیچیدهٔ سرور را از هر مکان action معتبر میدهد. فقط دو فیلد برای کلاینتها مرتبط هستند:
idشناسهٔ موجود در پایگاهدادهٔ action سرور برای اجرا
context(اختیاری)دادههای context برای استفاده هنگام اجرای action سرور
رکوردهای موجود در پایگاهداده بهطور قابل توجهی غنیتر هستند و میتوانند تعدادی action خاص یا عمومی را بر اساس state خود انجام دهند. برخی فیلدها (و رفتارهای متناظر) بین حالتها مشترک هستند:
model_idمدل Odoo که به action متصل است.
state
code: کد Python دادهشده از طریق آرگومانcodeرا اجرا میکند.object_create: یک رکورد جدید از مدلcrud_model_idبر اساس مشخصاتfields_linesایجاد میکند.object_write: رکورد(های) جاری را بر اساس مشخصاتfields_linesبهروزرسانی میکندmulti: چندین action دادهشده از طریق آرگومانchild_idsرا اجرا میکند.
فیلدهای حالت¶
بسته به state آن، رفتار از طریق فیلدهای مختلف تعریف میشود. state مربوطه بعد از هر فیلد ذکر شده است.
code(code)یک قطعه کد Python برای اجرا هنگام فراخوانی action مشخص کنید
<record model="ir.actions.server" id="print_instance"> <field name="name">Res Partner Server Action</field> <field name="model_id" ref="model_res_partner"/> <field name="state">code</field> <field name="code"> raise Warning(record.name) </field> </record>
توجه
بخش کد میتواند متغیری به نام
actionتعریف کند که بهعنوان action بعدی برای اجرا به کلاینت بازگردانده میشود:<record model="ir.actions.server" id="print_instance"> <field name="name">Res Partner Server Action</field> <field name="model_id" ref="model_res_partner"/> <field name="state">code</field> <field name="code"> if record.some_condition(): action = { "type": "ir.actions.act_window", "view_mode": "form", "res_model": record._name, "res_id": record.id, } </field> </record>
اگر رکورد شرط مشخصی را برآورده کند، از کلاینت میخواهد یک فرم برای رکورد باز کند
crud_model_id(create)(الزامی)مدلی که در آن رکورد جدیدی ایجاد میشود
link_field_id(create)many2one به
ir.model.fields، فیلد m2o رکورد جاری را مشخص میکند که رکورد تازه ایجاد شده باید روی آن تنظیم شود (مدلها باید مطابقت داشته باشند)fields_lines(create/write)فیلدهایی که هنگام ایجاد یا کپی کردن رکورد بازنویسی شوند.
One2manyبا فیلدهای:col1ir.model.fieldsبرای تنظیم در مدل مربوطه (crud_model_idبرای ایجاد،model_idبرای بهروزرسانی)valueمقدار فیلد، که از طریق
typeتفسیر میشودtype(value|reference|equation)اگر
valueباشد، فیلدvalueبهعنوان یک مقدار لیترال (با احتمال تبدیل) تفسیر میشود؛ اگرequationباشد، فیلدvalueبهعنوان یک عبارت Python تفسیر و ارزیابی میشود
child_ids(multi)چندین زیر-action (
ir.actions.server) را برای اجرا در state چندگانه مشخص کنید. اگر خود زیر-actionها action برمیگردانند، آخرین مورد بهعنوان action بعدی خود multi به کلاینت بازگردانده میشود
context ارزیابی¶
تعدادی کلید در context ارزیابی اکشنهای سرور یا پیرامون آنها در دسترس هستند:
modelشیء مدلی که از طریقmodel_idبه action متصل استrecord/recordsرکورد/recordset که action روی آن راهاندازی میشود، میتواند خالی باشد.envمحیط Odoodatetime،dateutil،time،timezoneماژولهای متناظر در Pythonlog: log(message, level='info')تابع لاگگیری برای ثبت اطلاعات اشکالزدایی در جدول ir.loggingWarningسازندهٔ استثنایWarning
اکشنهای گزارش (ir.actions.report)¶
Triggers the printing of a report.
If you define your report through a <record> instead of a <report> tag and
want the action to show up in the Print menu of the model's views, you will
also need to specify binding_model_id from بایندینگها. It's
not necessary to set binding_type to report, since
ir.actions.report will implicitly default to that.
name(mandatory)used as the file name if
print_report_nameis not specified. Otherwise, only useful as a mnemonic/description of the report when looking for one in a list of some sortmodel(mandatory)the model your report will be about
report_type(default=qweb-pdf)either
qweb-pdffor PDF reports orqweb-htmlfor HTMLreport_name(mandatory)the name (external id) of the qweb template used to render the report
print_report_namepython expression defining the name of the report.
groups_idMany2manyfield to the groups allowed to view/use the current reportmultiif set to
True, the action will not be displayed on a form view.paperformat_idMany2onefield to the paper format you wish to use for this report (if not specified, the company format will be used)attachment_useif set to
True, the report is only generated once the first time it is requested, and re-printed from the stored report afterwards instead of being re-generated every time.Can be used for reports which must only be generated once (e.g. for legal reasons)
attachmentpython expression that defines the name of the report; the record is accessible as the variable
object
Client Actions (ir.actions.client)¶
Triggers an action implemented entirely in the client.
tagthe client-side identifier of the action, an arbitrary string which the client should know how to react to
params(optional)a Python dictionary of additional data to send to the client, alongside the client action tag
target(اختیاری)whether the client action should be open in the main content area (
current), in full screen mode (fullscreen) or in a dialog/popup (new). Usemaininstead ofcurrentto clear the breadcrumbs. Defaults tocurrent.
{
"type": "ir.actions.client",
"tag": "pos.ui"
}
tells the client to start the Point of Sale interface, the server has no idea how the POS interface works.
همچنین ببینید
Scheduled Actions (ir.cron)¶
Actions triggered automatically on a predefined frequency.
nameName of the scheduled action (Mainly used in log display)
interval_numberNumber of interval_type uom between two executions of the action
interval_typeUnit of measure of frequency interval (
minutes,hours,days,weeks,months)model_idModel on which this action will be called
codeCode content of the action. Can be a simple call to the model's method :
model.<method_name>()
nextcallNext planned execution date of this action (date/time format)
priorityPriority of the action when executing multiple actions at the same time
Writing cron functions¶
When running a scheduled action, it's recommended that you try to batch the progress in order to avoid blocking a worker for a long period of time and possibly run into timeout exceptions. Therefore, you should split the processing so that each call makes progress on some of the work to be done.
When writing such a function, you should focus on processing a single batch. A batch should process one or many records and should generally take no more than a few seconds.
Work is committed by the framework after each batch. The framework will call the function as many times as necessary to process the remaining work. Do not reschedule yourself the job.
def _cron_do_something(self, *, limit=300): # limit: allows for tweaking
domain = [('state', '=', 'ready')]
records = self.search(domain, limit=limit)
records.do_something()
# notify progression
remaining = 0 if len(records) == limit else self.search_count(domain)
self.env['ir.cron']._commit_progress(len(records), remaining=remaining)
In some cases, you may want to share resources between multiple batches or
manage the loop yourself to handle exceptions.
In this case, you should inform the scheduler of the progress of your work
by calling IrCron._commit_progress() and checking the result. The progress
function returns the number of seconds remaining for the call; if it is 0, you
must return as soon as possible.
The following is an example of how to commit after each record that is processed, while keeping the connection open.
def _cron_do_something(self):
assert self.env.context.get('cron_id'), "Run only inside cron jobs"
domain = [('state', '=', 'ready')]
records = self.search(domain)
self.env['ir.cron']._commit_progress(remaining=len(records))
with open_some_connection() as conn:
for record in records:
# You may have other needs; we do some common stuff here:
# - lock record (also checks existence)
# - prefetch: break prefetch in this case, we process one record
# - filtered_domain: record may have changed
record = record.try_lock_for_update().filtered_domain(domain)
if not record:
continue
# Processing the batch here...
try
record.do_something(conn)
if not self.env['ir.cron']._commit_progress(1):
break
except Exception:
# if you handle exceptions, the default stategy is to
# rollback first the error
self.env.cr.rollback()
_logger.warning(...)
# you may commit some status using _commit_progress
Running cron functions¶
You should not call cron functions directly. There are two ways to run functions:
Testing of a cron function should be done by calling
IrCron.method_direct_trigger() in the registry test mode.
امنیت¶
To avoid a fair usage of resources among scheduled actions, some security measures ensure the correct functioning of your scheduled actions.
If a scheduled action encounters an error or a timeout three consecutive times, it will skip its current execution and be considered as failed.
If a scheduled action fails its execution five consecutive times over a period of at least seven days, it will be deactivated and will notify the DB admin.
A hard-limit exists for the cron execution at the database level after which the process executing cron jobs is killed.