两个字段的组合在 Python Eve 中是唯一的
Combination of two fields to be unique in Python Eve
在 Python Eve 框架中,是否可以有一个条件来检查两个字段的组合是否唯一?
例如,下面的定义仅限制 firstname 和 lastname 对于资源中的项目是唯一的。
people = {
# 'title' tag used in item links.
'item_title': 'person',
'schema': {
'firstname': {
'type': 'string',
'required': True,
'unique': True
},
'lastname': {
'type': 'string',
'required': True,
'unique': True
}
}
相反,有没有办法限制 firstname 和 lastname 的组合是唯一的?
或者有没有办法为此实现 CustomValidator?
您可能可以通过重载 _validate_unique
并在那里实现自定义逻辑来实现您想要的,利用 self.document
来检索其他字段值。
但是,由于每个唯一字段都会调用 _validate_unique
,因此您最终会执行两次自定义验证,一次是 firstname
,然后是 lastname
。不是很理想。当然,最简单的方法是设置 fullname
字段,但我想这不是您的选择。
您是否考虑过采用稍微不同的设计?类似于:
{'name': {'first': 'John', 'last': 'Doe'}}
那么你只需要确保 name
是必需的 并且 是唯一的:
{
'name': {
'type':'dict',
'required': True,
'unique': True,
'schema': {
'first': {'type': 'string'},
'last': {'type': 'string'}
}
}
}
灵感来自 Nicola 和 _validate_unique
。
from eve.io.mongo import Validator
from eve.utils import config
from flask import current_app as app
class ExtendedValidator(Validator):
def _validate_unique_combination(self, unique_combination, field, value):
""" {'type': 'list'} """
self._is_combination_unique(unique_combination, field, value, {})
def _is_combination_unique(self, unique_combination, field, value, query):
""" Test if the value combination is unique.
"""
if unique_combination:
query = {k: self.document[k] for k in unique_combination}
query[field] = value
resource_config = config.DOMAIN[self.resource]
# exclude soft deleted documents if applicable
if resource_config['soft_delete']:
query[config.DELETED] = {'$ne': True}
if self.document_id:
id_field = resource_config['id_field']
query[id_field] = {'$ne': self.document_id}
datasource, _, _, _ = app.data.datasource(self.resource)
if app.data.driver.db[datasource].find_one(query):
key_names = ', '.join([k for k in query])
self._error(field, "value combination of '%s' is not unique" % key_names)
在 Python Eve 框架中,是否可以有一个条件来检查两个字段的组合是否唯一?
例如,下面的定义仅限制 firstname 和 lastname 对于资源中的项目是唯一的。
people = {
# 'title' tag used in item links.
'item_title': 'person',
'schema': {
'firstname': {
'type': 'string',
'required': True,
'unique': True
},
'lastname': {
'type': 'string',
'required': True,
'unique': True
}
}
相反,有没有办法限制 firstname 和 lastname 的组合是唯一的?
或者有没有办法为此实现 CustomValidator?
您可能可以通过重载 _validate_unique
并在那里实现自定义逻辑来实现您想要的,利用 self.document
来检索其他字段值。
但是,由于每个唯一字段都会调用 _validate_unique
,因此您最终会执行两次自定义验证,一次是 firstname
,然后是 lastname
。不是很理想。当然,最简单的方法是设置 fullname
字段,但我想这不是您的选择。
您是否考虑过采用稍微不同的设计?类似于:
{'name': {'first': 'John', 'last': 'Doe'}}
那么你只需要确保 name
是必需的 并且 是唯一的:
{
'name': {
'type':'dict',
'required': True,
'unique': True,
'schema': {
'first': {'type': 'string'},
'last': {'type': 'string'}
}
}
}
灵感来自 Nicola 和 _validate_unique
。
from eve.io.mongo import Validator
from eve.utils import config
from flask import current_app as app
class ExtendedValidator(Validator):
def _validate_unique_combination(self, unique_combination, field, value):
""" {'type': 'list'} """
self._is_combination_unique(unique_combination, field, value, {})
def _is_combination_unique(self, unique_combination, field, value, query):
""" Test if the value combination is unique.
"""
if unique_combination:
query = {k: self.document[k] for k in unique_combination}
query[field] = value
resource_config = config.DOMAIN[self.resource]
# exclude soft deleted documents if applicable
if resource_config['soft_delete']:
query[config.DELETED] = {'$ne': True}
if self.document_id:
id_field = resource_config['id_field']
query[id_field] = {'$ne': self.document_id}
datasource, _, _, _ = app.data.datasource(self.resource)
if app.data.driver.db[datasource].find_one(query):
key_names = ', '.join([k for k in query])
self._error(field, "value combination of '%s' is not unique" % key_names)