我正在使用python-eve构建API。
我的设计很简单,它有两个资源,用户和设备:
代码是( settings.py ):
users_schema = {
'nickName': {
'type': 'string',
'required': True,
},
'email': {
'type': 'string',
'required': True,
'unique': True
}
}
devices_schema = {
'name': {
'type': 'string',
'required': True,
},
'user_id': {
'type': 'objectid',
'data_relation': {
'resource': 'users',
'embeddable': True
},
}
}
users = {
'item_title': 'user',
'url': 'users',
'schema': users_schema,
}
user_devices = {
'resource_title': 'devices',
'url': 'users/<regex("[a-f0-9]{24}"):user_id>/devices',
'schema': devices_schema,
'datasource': {
'source': 'devices',
}
}
DOMAIN = {
'users': users,
'user_devices': user_devices
}
如果我创建用户,则用户资源看起来像( / users / 54465ae80640fd0f60f6aa09 ):
{
"_updated": "Tue, 21 Oct 2014 13:08:56 GMT",
"_etag": "d6ff9457f5b196a8c245a7dc91e7fca0d28c5268",
"_links": {
"self": {
"href": "/users/54465ae80640fd0f60f6aa09",
"title": "user"
},
"parent": {
"href": "",
"title": "home"
},
"collection": {
"href": "/users",
"title": "users"
}
},
"_created": "Tue, 21 Oct 2014 13:08:56 GMT",
"_id": "54465ae80640fd0f60f6aa09",
"nickName": "superuser",
"email": "super@user.com"
}
默认情况下启用HATEOAS。 在之前的资源中,我期望链接到用户设备, / users / 54465ae80640fd0f60f6aa09 / devices ,因为此端点存在,在代码(user_devices)中定义,并且工作正常。
我可以让pyhon-eve了解用户和用户设备之间的关系,将此设备链接添加到用户资源?否则,用户54465ae80640fd0f60f6aa09将不知道如何获取设备。
我期待的是:
{
"_updated": "Tue, 21 Oct 2014 13:08:56 GMT",
"_etag": "d6ff9457f5b196a8c245a7dc91e7fca0d28c5268",
"_links": {
"self": {
"href": "/users/54465ae80640fd0f60f6aa09",
"title": "user"
},
"devices": {
"href": "/users/54465ae80640fd0f60f6aa09/devices",
"title": "devices"
},
"parent": {
"href": "",
"title": "home"
},
"collection": {
"href": "/users",
"title": "users"
}
},
"_created": "Tue, 21 Oct 2014 13:08:56 GMT",
"_id": "54465ae80640fd0f60f6aa09",
"nickName": "superuser",
"email": "super@user.com"
}
如何获取设备的“显而易见”。
非常感谢。
答案 0 :(得分:1)
您必须在user =&gt;之间添加链接设备太
users_schema = {
'nickName': {
'type': 'string',
'required': True,
},
'data_relation': {
'resource': 'user_devices', # link to device on a field _id
'field': '_id',
'embeddable': True
},
'email': {
'type': 'string',
'required': True,
'unique': True
}
}
答案 1 :(得分:0)
我创建了一个自定义钩子,以将一个项目与其他集合链接起来。
将下一个代码添加到您的应用中,然后定义您的商品和相关集合之间的data_relation。
例如,我有通过parent_node链接的菜单,因此我在架构上有两个关系:
所以我有下一个模式(孩子的第一个关系第二个给父母):
"menu": {
"type": "dict",
"schema": {
"_id": {
"type": "objectid",
"data_relation": {
"resource": "menu",
"field": "parent_menu",
"embeddable": False,
}
},
"id": { "type": "string" } ,
"label": { "type": "string" },
"url": { "type": "string" },
"parent_menu": {
"type": "objectid",
"data_relation": {
"resource": "menu",
"field": "_id",
"embeddable": True,
},
},
},
},
这是呈现根菜单的方式(不是父菜单,只有具有link_rel“ menu”的子菜单:
{
"_id":"5c6ab8a5467a938b027aae64",
"id":"root",
"label":"Home",
"url":"/",
"_links":{
...
"self":{
"title":"Menu",
"href":"menu/5c6ab8a5467a938b027aae64"
},
...
"menu":{
"title":"menu",
"href":"menu?where={\"parent_menu\":\"5c6ab8a5467a938b027aae64\"}"
}
}
}
这是孩子的样子(父母和孩子链接):
{
"_id":"5c6ab8a5467a938b027aae65",
"id":"submenu1",
"label":"Submenu1",
"url":"/#submenu1",
"parent_menu":"5c6ab8a5467a938b027aae64",
"_links":{
...
"self":{
"title":"Menu",
"href":"menu/5c6ab8a5467a938b027aae65"
},
...
"menu":{
"title":"menu",
"href":"menu?where={\"parent_menu\":\"5c6ab8a5467a938b027aae65\"}"
},
"parent_menu":{
"title":"menu",
"href":"menu/5c6ab8a5467a938b027aae64"
}
}
}
该应用的代码:
def createLink(ref_collection, ref_field, ref_value):
print(f"createLink({ref_collection}, {ref_field}, {ref_value})")
ref_value = f"{ref_value}"
linkSufix = "/" + ref_value if ref_field == "_id" else "?where={\"" + ref_field + "\":\"" + ref_value + "\"}"
linkRel = {
"title": ref_collection,
"href": ref_collection + linkSufix,
}
print(f"createLink result: \n{linkRel}")
return linkRel
def add_links(resource_name, resource, schema):
linked_item_keys = list(key for key in schema if "data_relation" in schema[key] and key in resource)
print(f"linked_item_keys: {linked_item_keys}")
for key in linked_item_keys:
print(f"link needed for: {resource_name}.{key}")
itemSchema = schema[key]
item = resource[key]
data_relation = itemSchema["data_relation"]
ref_collection = data_relation["resource"]
ref_field = data_relation["field"]
link = createLink(ref_collection, ref_field, item)
links = resource["_links"] if "_links" in resource else []
link_rel = ref_collection if resource_name == ref_collection and key == "_id" else key
links[link_rel] = link
resource["_links"] = links
def add_links_to_item(resource_name, response):
print(f"------------------------------------")
print(f"(on_fetched_item) {resource_name} ")
print(f"response: \n{response}")
schema = config.DOMAIN[resource_name]["schema"]
print(f"""schema: \n{schema}""")
add_links(resource_name, response, schema)
app = Eve()
app.on_fetched_item += add_links_to_item
希望有帮助!