python -m ensurepip --default-pip
Postgres backup and restore
# backup
pg_dump example -F t -N views --no-owner -h host -U user --role=postgres -v > example.tar
# restore
pg_restore --dbname=example -h localhost -U user -v example.tar
How to get Odoo selection field labels with translation
Inside Model
def _get_selections_label(self, field):
return self._fields[field].get_description(self.env).get('selection')
def _get_selection_label(self, field):
return dict(self._get_selections_label(field)).get(getattr(self, field))
Inside template
<span t-out="object._get_selection_label('field')"/>
Odoo reload page action
#on your model create an action method
...
def action_reload(self):
return {
'type': 'ir.actions.client',
'tag': 'reload',
}
Odoo string domain to python domain
import ast
# String domain
domain_str = "[('field_name', '=', 'field_value')]"
# Convert string to domain
converted_domain = ast.literal_eval(domain_str)
print("Original domain:", domain_str, type(domain_str))
print("Converted domain:", converted_domain, type(converted_domain))
How to reuse model field selection choices in Odoo?
We will increase the available choices of a model and reuse those new choices in another model
class FleetVehicleModel(models.Model):
_inherit = 'fleet.vehicle.model'
vehicle_type = fields.Selection(selection_add=VEHICLE_TYPE,
ondelete={'truck': 'set default', 'dredge': 'set default', 'bus': 'set default', 'micro_bus': 'set default'})
by default the vehicle type has car and bike choices and with the previous code it will have the new defined choices and the default ones.
class FleetVehicle(models.Model):
_inherit = 'fleet.vehicle'
def _selection_vehicle_type(self):
return self.env['fleet.vehicle.model']._columns['vehicle_type'].selection
vehicle_type = fields.Selection(_selection_vehicle_type, required=True)
Odoo 16 model creation guideline
- Method conventions
- Compute Field : the compute method pattern is _compute_<field_name>
- Search method : the search method pattern is _search_<field_name>
- Default method : the default method pattern is _default_<field_name>
- Selection method: the selection method pattern is _selection_<field_name>
- Onchange method : the onchange method pattern is _onchange_<field_name>
- Constraint method : the constraint method pattern is _check_<constraint_name>
- Action method : an object action method is prefix with action_. Since it uses only one record, add
self.ensure_one()
at the beginning of the method.
- In a Model attribute order should be
- Private attributes (
_name
,_description
,_inherit
,_sql_constraints
, …) - Default method and
default_get
- Field declarations
- Compute, inverse and search methods in the same order as field declaration
- Selection method (methods used to return computed values for selection fields)
- Constrains methods (
@api.constrains
) and onchange methods (@api.onchange
) - CRUD methods (ORM overrides)
- Action methods
- And finally, other business methods.
- Private attributes (
class Event(models.Model):
# Private attributes
_name = 'event.event'
_description = 'Event'
# Default methods
def _default_name(self):
...
# Fields declaration
name = fields.Char(string='Name', default=_default_name)
seats_reserved = fields.Integer(string='Reserved Seats', store=True
readonly=True, compute='_compute_seats')
seats_available = fields.Integer(string='Available Seats', store=True
readonly=True, compute='_compute_seats')
price = fields.Integer(string='Price')
event_type = fields.Selection(string="Type", selection='_selection_type')
# compute and search fields, in the same order of fields declaration
@api.depends('seats_max', 'registration_ids.state', 'registration_ids.nb_register')
def _compute_seats(self):
...
@api.model
def _selection_type(self):
return []
# Constraints and onchanges
@api.constrains('seats_max', 'seats_available')
def _check_seats_limit(self):
...
@api.onchange('date_begin')
def _onchange_date_begin(self):
...
# CRUD methods (and name_get, name_search, ...) overrides
def create(self, values):
...
# Action methods
def action_validate(self):
self.ensure_one()
...
# Business methods
def mail_user_confirm(self):
...
How to open gnome terminal from a cron job in Linux?
Open your user cron jobs using
crontab -e
Once inside your cron jobs insert the following at the bottom
00 * * * * env DISPLAY=:0 /usr/bin/dbus-launch /usr/bin/gnome-terminal
This will execute every hour at 00 minutes. Notice the full path for the dbus-launch and gnome-terminal
the env DISPLAY=:0 is to properly link the UI with the cron. The value :0 may vary so to make sure what value to use execute
echo $DISPLAY
Docker Main commands
#Pull image
docker pull image:version
#example
docker pull nginx:1.22
#view all docker images
docker images
#start your Docker container
docker run -d -p 8080:80 --name <container-name> <image-name>
#example
docker run -d -p 8080:80 --name nginx-container nginx
# --name set containers name
# -p maps the ports of container
# -d detach from console
#view running container
docker ps
#display all containers running or not
docker ps -a
# start container
docker start <container-name>
# stop container
docker stop <container-name>
#build custom image from Docker file
touch Dockerfile
# Edit content with
FROM nginx:latest
COPY ./index.html /usr/share/nginx/html/index.html
#build command
docker build -t <image-name> .
#check image
docker images
#start your Docker container
docker run -d -p 8080:80 --name <container-name> <image-name>
#remove container
docker rm <id or name>
#remove image
docker image rm <id or name>
#list volume
docker volume ls
#remove volume
docker volume rm <name>
Docker resources that are dangling (not tagged or associated with a container):
docker system prune
Remove any stopped containers and all unused images:
docker system prune -a
How to prevent recreation of xml record data in Odoo
<odoo>
<data noupdate="1">
<record id="planning_full_organizer_manager_role" forcecreate="0" model="res.users.role">
<field name="name">Full Organizer Manager Role</field>
</record>
</data>
</odoo>
<odoo noupdate="1">
<!-- <delete search="[('id','=',ref('planning_event_app.planning_stock_client_manager_role'))]"-->
<!-- model='res.users.role'/>-->
<delete search="[('id','=',ref('planning_event_app.planning_full_organizer_manager_role'))]"
model='res.users.role'/>
</odoo>
Even while having noupdate = 1 if the record gets deleted using another xml data odoo will recreate the record. To prevent this behavior of recreation must use the attribute forcecreate=0 as shown previously.