{"id":547,"date":"2025-08-22T13:40:20","date_gmt":"2025-08-22T13:40:20","guid":{"rendered":"https:\/\/sienna-manatee-218967.hostingersite.com\/blogs\/edicion-de-vistas-con-python\/"},"modified":"2026-05-01T18:54:35","modified_gmt":"2026-05-01T18:54:35","slug":"edicion-de-vistas-con-python","status":"publish","type":"post","link":"https:\/\/exdoo.mx\/blogs\/edicion-de-vistas-con-python\/","title":{"rendered":"Edici\u00f3n de vistas con Python"},"content":{"rendered":"<div style=\"background:linear-gradient(135deg,#0A7099 0%,#0d8db8 100%);color:#fff;padding:28px 26px;border-radius:16px;margin:0 0 28px;box-shadow:0 4px 16px rgba(10,112,153,.2);\">\n<div style=\"display:inline-block;background:rgba(255,255,255,.18);padding:6px 14px;border-radius:20px;font-size:12px;font-weight:700;letter-spacing:.5px;margin-bottom:12px;color:#fff;\">\ud83d\udcd8 ART\u00cdCULO T\u00c9CNICO<\/div>\n<p style=\"font-size:16px;line-height:1.6;margin:0;color:#fff;opacity:.95;\">\u00bfC\u00f3mo se pueden editar las vistas utilizando Python?<\/p>\n<\/div>\n<p><img decoding=\"async\" src=\"https:\/\/exdoo.mx\/blogs\/wp-content\/uploads\/2026\/05\/python-b-YanJNZV1rxfDyM6E-1.png\" alt=\"\"  style=\"max-width:100%;height:auto;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,0.12);display:block;margin:14px auto;\" \/><\/p>\n<div style=\"background:linear-gradient(135deg,#0A7099 0%,#0d8db8 100%);color:#fff;padding:28px 26px;border-radius:16px;margin:0 0 28px;box-shadow:0 4px 16px rgba(10,112,153,.2);\">\n<div style=\"display:inline-block;background:rgba(255,255,255,.18);padding:6px 14px;border-radius:20px;font-size:12px;font-weight:700;letter-spacing:.5px;margin-bottom:12px;color:#fff;\">\ud83d\udcd8 ART\u00cdCULO T\u00c9CNICO<\/div>\n<\/div>\n<p class=\"body\" dir=\"auto\"><span>Se depende principalmente de las siguientes dos funciones:<\/span><\/p>\n<p class=\"body\" dir=\"auto\"><span><strong><em>_get<\/em>_<em>view<\/em><\/strong><\/span><\/p>\n<p class=\"body\" dir=\"auto\"><span>Reemplaza al antiguo m\u00e9todo <em>fields_view_get<\/em> (utilizado hasta Odoo 15) y se desencadena cada vez que se carga una vista en el usuario (formulario, lista, kanban, etc.). Retorna una tupla (arch, view) donde:<\/span><\/p>\n<p class=\"body\" dir=\"auto\"><span>\u25cf arch: es el XML analizado de la vista (un nodo etree que admite operaciones XPath).<\/span><\/p>\n<p class=\"body\" dir=\"auto\"><span>\u25cf view: es el registro <em>ir.ui.view<\/em> asociado.<\/span><\/p>\n<p class=\"body\" dir=\"auto\"><span>Esta funci\u00f3n permite cambiar etiquetas (string) de campos din\u00e1micamente, modificar atributos seg\u00fan condiciones (como empresa activa o grupos de usuario) o adaptar visualizaci\u00f3n sin duplicar vistas en XML.<\/span><\/p>\n<p class=\"body\" dir=\"auto\"><span><strong><em>_get<\/em>_<em>view_cache_key<\/em><\/strong><\/span><\/p>\n<p class=\"body\" dir=\"auto\"><span>Est\u00e1 vinculado al sistema de cacheado de vistas de Odoo. Permite construir una clave \u00fanica para cada combinaci\u00f3n de vista m\u00e1s contexto, de tal manera que diferentes usuarios o situaciones puedan tener vistas personalizadas sin que se reutilicen vistas de otros contextos.<\/span><\/p>\n<p class=\"body\" dir=\"auto\"><span>Cuando se sobreescribe _<em>get_view<\/em> para personalizar vistas seg\u00fan contexto (por ejemplo, empresa o grupo), conviene redefinir _<em>get_view_cache_key<\/em> para que la cach\u00e9 considere esas condiciones adicionales.<\/span><\/p>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span><em><u>Usos y ejemplos<\/u><\/em><\/span><\/h3>\n<p class=\"body\" dir=\"auto\"><span>El ejemplo m\u00e1s conocido en los m\u00f3dulos base de Odoo es en las monedas, donde existe una columna llamada \u201cUnidad por X\u201d, siendo X el nombre de la moneda de la comp<\/span><span>a\u00f1\u00eda:<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/exdoo.mx\/blogs\/wp-content\/uploads\/2026\/05\/1-YKblqvy4vntRnwga-1.png\" alt=\"\"  style=\"max-width:100%;height:auto;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,0.12);display:block;margin:14px auto;\" \/><\/p>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span>Si se cambiara el nombre de esa moneda, el nombre de esa columna no se podr\u00eda cambiar din\u00e1micamente utilizando las funcionalidades est\u00e1ndar de Odoo para la edici\u00f3n de vistas, por lo que utilizando las funciones anteriores se logra que esta columna tenga el nuevo nombre de la moneda. Por ejemplo, se modifica el nombre de la moneda de MXN a MX, y ese nuevo nombre se visualiza en la columna:<\/span><\/h3>\n<p><img decoding=\"async\" src=\"https:\/\/exdoo.mx\/blogs\/wp-content\/uploads\/2026\/05\/2-Yyv0wQoejpuZp0Vx-1.png\" alt=\"\"  style=\"max-width:100%;height:auto;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,0.12);display:block;margin:14px auto;\" \/><br \/>\n<img decoding=\"async\" src=\"https:\/\/exdoo.mx\/blogs\/wp-content\/uploads\/2026\/05\/3-dOqDQ6bLlKiDEZN3-1.png\" alt=\"\"  style=\"max-width:100%;height:auto;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,0.12);display:block;margin:14px auto;\" \/><\/p>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span><strong>Ejemplo de edici\u00f3n de una vista utilizando Python<\/strong><\/span><\/h3>\n<p class=\"body\" dir=\"auto\"><span>Supongamos que queremos editar din\u00e1micamente la vista formulario de las cotizaciones dependiendo de si el usuario tiene o no el permiso <strong>\u201cVentas \/ Administrador\u201d<\/strong>, mismo que est\u00e1 dentro del m\u00f3dulo de ventas.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/exdoo.mx\/blogs\/wp-content\/uploads\/2026\/05\/4-YrDJxoqLyecVMNNJ-1.png\" alt=\"\"  style=\"max-width:100%;height:auto;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,0.12);display:block;margin:14px auto;\" \/><\/p>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span>Si el usuario tiene este permiso, podr\u00e1 ver todos los botones del elemento &lt;header&gt; de la vista formulario; de lo contrario, no ver\u00e1 ning\u00fan bot\u00f3n ni el widget de estado. Dentro de una clase que herede a \u2018sale.order\u2019, el c\u00f3digo se estructura de la siguiente manera:<\/span><\/h3>\n<p class=\"body\" dir=\"auto\"><span><strong><em>_get<\/em>_<em>view_cache_key<\/em><\/strong><\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/exdoo.mx\/blogs\/wp-content\/uploads\/2026\/05\/5-YrDJxoJbjzC5gnrG-1.png\" alt=\"\"  style=\"max-width:100%;height:auto;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,0.12);display:block;margin:14px auto;\" \/><\/p>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span>donde:<\/span><\/h3>\n<p dir=\"auto\" class=\"body\"><span>\u25cfkey es el resultado original de la funci\u00f3n _<em>get_<\/em>view_cache_key.<\/span><\/p>\n<p dir=\"auto\" class=\"body\"><span>\u25cfAl resultado de key le agregamos la condici\u00f3n de si el usuario tiene el permiso \u2018sales_<a target=\"_blank\" rel=\"noopener noreferrer\" class=\"qbe-widget\" href=\"http:\/\/team.group\">team.group<\/a>_sale_manager\u2019 (nombre t\u00e9cnico del permiso \u201cVentas \/ Administrador\u201d). As\u00ed, si el usuario cambia el tener o no este permiso, la clave de la cach\u00e9 tambi\u00e9n cambia y fuerza que se regenere la vista seg\u00fan las condiciones que definimos en la siguiente funci\u00f3n.<\/span><\/p>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span><strong><em>_get<\/em>_<em>view<\/em><\/strong><\/span><\/h3>\n<p><img decoding=\"async\" src=\"https:\/\/exdoo.mx\/blogs\/wp-content\/uploads\/2026\/05\/6-AoPJ3n0xE5sbJw7D-1.png\" alt=\"\"  style=\"max-width:100%;height:auto;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,0.12);display:block;margin:14px auto;\" \/><\/p>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span>donde:<\/span><\/h3>\n<p dir=\"auto\" class=\"body\"><span>\u25cfarch y view son los resultados originales de la funci\u00f3n _<em>get_<\/em>view.<\/span><\/p>\n<p dir=\"auto\" class=\"body\"><span>\u25cfValidamos si el tipo de vista es formulario (form), que es donde haremos los cambios, y si el usuario tiene o no el permiso de usuario. De ser que se cumplan las condiciones necesarias, modificamos la vista buscando el nodo utilizando XPath y, si encontramos el nodo, a\u00f1adimos el par\u00e1metro invisible=&#8221;1&#8243; (que sea invisible).<\/span><\/p>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span>Por lo que, si no tenemos el permiso indicado, la vista se visualiza de la siguiente manera:<\/span><\/h3>\n<p><img decoding=\"async\" src=\"https:\/\/exdoo.mx\/blogs\/wp-content\/uploads\/2026\/05\/7-Awv96E535aHrqgvZ-1.png\" alt=\"\"  style=\"max-width:100%;height:auto;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,0.12);display:block;margin:14px auto;\" \/><\/p>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span>Al colocarnos el permiso de nuevo, se visualizan los botones y la barra de estado con normalidad.<\/span><\/h3>\n<p><img decoding=\"async\" src=\"https:\/\/exdoo.mx\/blogs\/wp-content\/uploads\/2026\/05\/8-YBgb2LLBwXHxQ8Qx-1.png\" alt=\"\"  style=\"max-width:100%;height:auto;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,0.12);display:block;margin:14px auto;\" \/><\/p>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span>Supongamos que \u00fanicamente quisi\u00e9ramos ocultar el bot\u00f3n \u2018Enviar por correo electr\u00f3nico\u2019, por lo que el c\u00f3digo se modifica de la siguiente manera:<\/span><\/h3>\n<p><img decoding=\"async\" src=\"https:\/\/exdoo.mx\/blogs\/wp-content\/uploads\/2026\/05\/9-AE0r15M63bUyVq9K-1.png\" alt=\"\"  style=\"max-width:100%;height:auto;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,0.12);display:block;margin:14px auto;\" \/><\/p>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span>Por lo que, si no tuvi\u00e9semos el permiso, la vista se visualizar\u00eda de la siguiente manera:<\/span><\/h3>\n<p><img decoding=\"async\" src=\"https:\/\/exdoo.mx\/blogs\/wp-content\/uploads\/2026\/05\/1-AzGNQErkjvIoLQE7-1.png\" alt=\"\"  style=\"max-width:100%;height:auto;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,0.12);display:block;margin:14px auto;\" \/><\/p>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span>Aunque la modificaci\u00f3n de vistas desde Python no es solo ocultar partes de la vista, sino agregar o quitar par\u00e1metros, nuevos nodos o el propio valor de los par\u00e1metros. Un ejemplo burdo es que, si el usuario tiene el permiso, el bot\u00f3n se visualiza y tiene un texto diferente.<\/span><\/h3>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span> Esto lo logramos reestructurando el c\u00f3digo de la siguiente manera.<\/span><\/h3>\n<p><img decoding=\"async\" src=\"https:\/\/exdoo.mx\/blogs\/wp-content\/uploads\/2026\/05\/2-mxBXJE27OnHpVva3-1.png\" alt=\"\"  style=\"max-width:100%;height:auto;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,0.12);display:block;margin:14px auto;\" \/><\/p>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span>Por lo que si tenemos el permiso de usuario, la vista se ve de la siguiente manera:<\/span><\/h3>\n<p><img decoding=\"async\" src=\"https:\/\/exdoo.mx\/blogs\/wp-content\/uploads\/2026\/05\/3-AR03G5NOrrtapBz4-1.png\" alt=\"\"  style=\"max-width:100%;height:auto;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,0.12);display:block;margin:14px auto;\" \/><\/p>\n<h3 style=\"color:#0A7099;margin-top:24px;\"><span><strong>Consejos r\u00e1pidos:<\/strong><\/span><\/h3>\n<p dir=\"auto\" class=\"body\"><span>\u25cf Usa _<em>get<\/em>_view&nbsp;para ajustes ligeros; por ejemplo, cambia etiquetas (string), atributos (readonly, invisible) o incluso a\u00f1ade nodos al XML sin necesidad de duplicar vistas.<\/span><\/p>\n<p dir=\"auto\" class=\"body\"><span>\u25cfLocaliza campos o secciones espec\u00edficas de la vista con expresiones XPath para mantener tu c\u00f3digo limpio y preciso.<\/span><\/p>\n<p dir=\"auto\" class=\"body\"><span>\u25cfReserva _<em>get_<\/em>view para cambios din\u00e1micos que no pueden resolverse con herencias XML normales.<\/span><\/p>\n<p dir=\"auto\" class=\"body\"><span>\u25cfSi tus cambios dependen de contexto (ej., compa\u00f1\u00eda, grupos de usuario), redefine _<em>get_<\/em>view_cache_key para que cada situaci\u00f3n tenga su propia versi\u00f3n en memoria.<\/span><\/p>\n<p dir=\"auto\" class=\"body\"><span>\u25cfA\u00f1ade solo los elementos relevantes al cache key (por ejemplo, company_id o user_has_groups) para evitar duplicaciones innecesarias.<\/span><\/p>\n<p dir=\"auto\" class=\"body\"><span>\u25cfAseg\u00farate de que la personalizaci\u00f3n se aplica correctamente al cambiar de compa\u00f1\u00eda, grupo o rol.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udcd8 ART\u00cdCULO T\u00c9CNICO \u00bfC\u00f3mo se pueden editar las vistas utilizando Python? \ud83d\udcd8 ART\u00cdCULO T\u00c9CNICO Se depende principalmente de las siguientes dos funciones: _get_view Reemplaza al antiguo m\u00e9todo fields_view_get\u2026<\/p>\n","protected":false},"author":1,"featured_media":533,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-547","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/exdoo.mx\/blogs\/wp-json\/wp\/v2\/posts\/547","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/exdoo.mx\/blogs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/exdoo.mx\/blogs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/exdoo.mx\/blogs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/exdoo.mx\/blogs\/wp-json\/wp\/v2\/comments?post=547"}],"version-history":[{"count":3,"href":"https:\/\/exdoo.mx\/blogs\/wp-json\/wp\/v2\/posts\/547\/revisions"}],"predecessor-version":[{"id":1966,"href":"https:\/\/exdoo.mx\/blogs\/wp-json\/wp\/v2\/posts\/547\/revisions\/1966"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/exdoo.mx\/blogs\/wp-json\/wp\/v2\/media\/533"}],"wp:attachment":[{"href":"https:\/\/exdoo.mx\/blogs\/wp-json\/wp\/v2\/media?parent=547"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/exdoo.mx\/blogs\/wp-json\/wp\/v2\/categories?post=547"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/exdoo.mx\/blogs\/wp-json\/wp\/v2\/tags?post=547"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}