在Python Eve中,两个字段的组合是唯一的

时间:2015-06-03 14:36:57

标签: python eve

在Python Eve框架中,是否有可能检查两个字段的组合是唯一的条件?

例如,以下定义仅限制名字姓氏对资源中的项目是唯一的。

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
        }
}

相反,有没有办法将名字姓氏组合限制为唯一?

或者有没有办法为此实现CustomValidator?

2 个答案:

答案 0 :(得分:1)

您可以通过重载_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'}
        }
    }
}

答案 1 :(得分:0)

受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)