我有一个带有旧版UUID _id字段的MongoDB集合。
我可以通过传递UUID对象来检索pymongo的单个对象:
from uuid import UUID
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client[DB_NAME]
collection = db[COLLECTION_NAME]
one_ok = collection.find_one(
filter={'_id': UUID('eedacde6-e241-4f37-a57d-c4e8eb6601a7')})
one_not_ok = collection.find_one(
filter={'_id': 'eedacde6-e241-4f37-a57d-c4e8eb6601a7'})
print(one_ok is None) # prints False
print(one_not_ok is None) # prints True
然而,我似乎无法使用Eve获得个人资源。我得到了404:
http://localhost:5000/collection1/eedacde6-e241-4f37-a57d-c4e8eb6601b7
http://localhost:5000/collection1
返回的列表提到的链接collection1/eedacde6-e241-4f37-a57d-c4e8eb6601b7
似乎与返回404的网址相匹配:
<resource href="collection1" title="collection1">
<link rel="parent" href="/" title="home"/>
<_meta>
<max_results>25</max_results>
<page>1</page>
<total>2</total>
</_meta>
<resource href="collection1/eedacde6-e241-4f37-a57d-c4e8eb6601b7" title="Collection1">
<_created>Thu, 01 Jan 1970 00:00:00 GMT</_created>
<_etag>9718572fe2d17b12358691602f6bd5f1ee345b06</_etag>
<_id>eedacde6-e241-4f37-a57d-c4e8eb6601b7</_id>
<_updated>Thu, 01 Jan 1970 00:00:00 GMT</_updated>
</resource>
<resource href="collection1/98c67ae6-ee7b-4bd3-9ec1-56b70fa2a9c7" title="Collection1">
<_created>Thu, 01 Jan 1970 00:00:00 GMT</_created>
<_etag>75c2451d19750e1007274315672bf893f9654273</_etag>
<_id>98c67ae6-ee7b-4bd3-9ec1-56b70fa2a9c7</_id>
<_updated>Thu, 01 Jan 1970 00:00:00 GMT</_updated>
</resource>
</resource>
这是我在settings.py中的DOMAIN变量。我按照http://python-eve.org/tutorials/custom_idfields.html后的那种方式进行了设置。
DOMAIN = {
'collection1': {
'item_url': 'regex("[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}")',
'schema': {
'_id': {'type': 'uuid'},
},
}
}
我怀疑这不起作用,因为UUID是&#39; Legacy UUIDs&#39;但我可能错了。
关于如何制作http://localhost:5000/collection1/eedacde6-e241-4f37-a57d-c4e8eb6601b7
等网址的任何想法都会返回个人资源?
我能够通过黑客攻击来使它成功。必须为每个HTTP动词(GET,POST等)添加以下代码。
在eve/methods/get.py
def getitem_internal(resource, **lookup):
"""
<...>
"""
req = parse_request(resource)
resource_def = config.DOMAIN[resource]
embedded_fields = resolve_embedded_fields(resource, req)
#### hack ###
if '_id' in lookup:
if 'schema' in resource_def and '_id' in resource_def['schema']:
if resource_def['schema']['_id'].get('type') == 'uuid':
lookup['_id'] = UUID(lookup['_id'])
#### end of hack ###
soft_delete_enabled = config.DOMAIN[resource]['soft_delete']
if soft_delete_enabled:
# GET requests should always fetch soft deleted documents from the db
# They are handled and included in 404 responses below.
req.show_deleted = True
document = app.data.find_one(resource, req, **lookup)
<...>