neutron/objects/base.py
@six.add_metaclass(DeclarativeObject)
class NeutronDbObject(NeutronObject)
fields
对应 object 模型里面的字段obj_extra_fields
,非模型字段的额外属性,提供这些数据有利于更容易的使用该对象fields_no_update
更新操作时不需要操作的属性fields_need_translation
属性在 object 里面的名称与在 db 里面名称的对应关系({'field_name_in_object': 'field_name_in_db'}
)unique_keys
代表着数据库中独一无二的字段extra_filter_names
,用户可以那这个选项进行数据的查询,但是这个选项却不可以用到数据库的查询中,在进行数据库查询前,需要将这个查询选项删除掉。synthetic_fields
标记着与当前 object 有关系的其他 object(也就是数据库中的一对一、一对多、多对多的关系orm.relationship
)。_changed_fields
,若对该 object 的某一属性设置过值,则会在_changed_fields
属性中进行记录,调用obj_reset_changes
会清除记录。
这是 NeutronDbObject
的元类,我们看这个里面实现的功能
- 若是
NeutronDbObject
或者其子类的fields
中含有project_id
,则将tenant_id
加入到obj_extra_fields
中,同时为改类设置tenant_id
的属性方法(这里有个技巧,请看源码)。 - 取类以及其基类的
primary_keys
和obj_extra_fields
数据,将其更新到 设置为fields_no_update
属性。 - 若是类中设置了
db_model
属性,则从对应的数据模型中提取出unique_keys
,然后使用_detach_db_obj
方法修饰类的create
和update
方法。 - 若是该类有
has_standard_attributes
属性且has_standard_attributes
方法调用为真的话,则调用standardattributes.add_standard_attributes
来更新类的fields
- 设定
extra_filter_names
属性
这个类是 Neutron 中所有 object 的基类
返回该 object 是从哪个数据库记录转化来的,也就是返回 _captured_db_model
属性
类方法,从数据库中提取记录,并将其转化为versioned object。
**kwargs
是指数据库的过滤字段
- 判断
**kwargs
是否在对象的primary_keys
和unique_keys
中。 - 调用
modify_fields_to_db
实现对象名称到数据库名称的转换 - 调用
get_object
(objects 中的数据库操作方法) 获取数据库记录 - 若存在数据库记录,则调用
_load_object
将数据库记录转化为 versioned object。
类方法,实现对象名称到数据库字段名称的转换。(利用 fields_need_translation
属性)
- 实例化此 Object
- 调用
from_db_object
将数据库记录转化为 versioned object。 - 从数据库会话中去掉实例(数据库中还是存在的)。
- 调用
modify_fields_from_db
将数据库记录转化为 object 记录。 - 调用
load_synthetic_db_fields
加载与当前对象有关系的 object(synthetic_fields
)。 - 设置
_captured_db_model
属性 - 调用
obj_reset_changes
清除所有的被改变过属性的记录。
提取数据库记录的数据,并根据 fields_need_translation
将数据库名称转换为 object 名称。
处理 synthetic_fields
中保存的该 object 与其他 object 的对应关系。
在这里会加载与该 object 有关的其他 object。
清除 _changed_fields
的记录。
- 若设置了
recursive
为 True,则对于该 object 有关系的 object 也执行obj_reset_changes
操作。 - 若
fields
不为空,则之删除fields
记录。 - 若
fields
为空,则删除所有记录。
调用 obj_what_changed
获取当前 object 被改变的属性。
返回被改变的属性,及其该属性的当前值。
返回当前 object 被修改的属性名称,若是与该 object 相关的 object 的属性也被修改过的话,则相关 object 的名称也要加入到其中。
获取数据库中的多个对象。
-
_pager 用于分页和排序
-
validate_filters 为 true 时,检测过滤参数(
**kwargs
)是否正确 -
调用
validate_filters
验证数据库过滤参数 -
调用
modify_fields_to_db
将 object 的属性转化为数据库认识的属性 -
调用数据库方法
obj_db_api.get_objects
获取查询结果 -
调用
_load_object
将所有查询到的结果转化为 versioned object
将对象形式的 fields 转化为数据库形式的 fields,主要和 fields_need_translation
属性有关
根据 context 判断是否有权限访问这个数据库记录(db_obj
)
将 value 转化为字符串格式
@staticmethod
def filter_to_str(value):
if isinstance(value, list):
return [str(val) for val in value]
return str(value)
创建数据库记录
- 调用
_get_changed_persistent_fields
获取被改变了的 field - 调用
modify_fields_to_db
将 object 的 field 转化为数据库识别的字段 - 调用数据库方法
obj_db_api.create_object
创建数据库记录 - 若数据库记录创建成功,则调用
from_db_object
加载新创建的数据库记录的属性(也就是当前的 object 要和新的数据库记录关联起来了)。
获取被修改过的 field,在其中排除非本 object 对应数据库的字段
def _get_changed_persistent_fields(self):
fields = self.obj_get_changes()
for field in self.synthetic_fields:
if field in fields:
del fields[field]
return fields
更新数据库记录
- 调用
_get_changed_persistent_fields
获取被改变了的 field - 调用
_validate_changed_fields
验证是否存在不允许更新的字段 - 调用
_get_composite_keys
获取 primary key,并根据 primary key 获取数据库记录 - 调用
modify_fields_to_db
将 object 的 field 转化为数据库的字段 - 调用
obj_db_api.update_object
更新数据库记录
类属性 fields_no_update
存储着 object (数据库)不允许更新的字段
该方法就是检测 fields 中是否含有了不允许更新的字段
获取 primary key
def _get_composite_keys(self):
keys = {}
for key in self.primary_keys:
keys[key] = getattr(self, key)
return keys
更新 object 的 fields,而不是更新 object 对应数据库的数据。
若 reset_changes
为 True,则调用 obj_reset_changes
方法清空 object 的更新记录。
def update_fields(self, obj_data, reset_changes=False):
if reset_changes:
self.obj_reset_changes()
for k, v in obj_data.items():
if k not in self.fields_no_update:
setattr(self, k, v)
- 调用
_get_composite_keys
获取 primary keys - 调用
modify_fields_to_db
将 object field 转化为数据库字段 - 调用
obj_db_api.delete_object
删除这条数据库记录 - 设
_captured_db_model
属性为空
- 调用
validate_filters
验证过滤参数**kwargs
是否合法 - 调用
obj_db_api.count
获取数据库查询到记录的数量
@six.add_metaclass(abc.ABCMeta)
class NeutronObject(obj_base.VersionedObject,
obj_base.VersionedObjectDictCompat,
obj_base.ComparableVersionedObject)
synthetic_fields = []
extra_filter_names = set()
def __init__(self, context=None, **kwargs):
super(NeutronObject, self).__init__(context, **kwargs)
self.obj_set_defaults()
主要是调用 obj_set_defaults
为对象的属性设置默认值。
验证过滤参数是否正确
在 extra_filter_names
属性中增加新的项目
def _synthetic_fields_items(self):
for field in self.synthetic_fields:
if field in self:
yield field, getattr(self, field)
@classmethod
def is_synthetic(cls, field):
return field in cls.synthetic_fields
@classmethod
def is_object_field(cls, field):
return (isinstance(cls.fields[field], obj_fields.ListOfObjectsField) or
isinstance(cls.fields[field], obj_fields.ObjectField))
- 调用
obj_from_primitive
从 primitive 中构造一个 object - 调用
obj_reset_changes
清除新的 object 中的 changed_field
以字典的形式来展示 object 的 primitive 数据。
这个方法要比 obj_to_primitive
方法获取的 primitive 数据少一些属性,只相当于其中的 data
。
从 session 中分离(删除)db_obj,这是个装饰器方法
从数据模型 model 获取 object 的最新类
获取 object (cls
)中可更新的 field。
- 调用
get_object_class_by_model
根据模型获取 object 类 - 调用 object 的
add_extra_filter_name
增加额外的过滤选项