背景
我想确保无法在同一个用户中添加相同的用户。
结构化子类属性代码(包含用户集合的属性)是
from google.appengine.ext import ndb
class MembersStructuredProperty(ndb.StructuredProperty):
def _validate(self, value):
if value in self:
raise Exception('Duplicate detected')
def _call_to_base_type(self, value):
return value
def _call_from_base_type(self, value):
return value
使用上述属性的Model代码是
from google.appengine.ext import ndb
from mainsite.rainbow.models.CFCSocialUser import CFCSocialUser
from mainsite.rainbow.models.CFCBaseModel import BaseModel
from mainsite.rainbow.models.properties.CFCMembersStructuredProperty import MembersStructuredProperty
class CFCSocialGroup(BaseModel):
name = ndb.StringProperty(required=True)
created_by = ndb.StructuredProperty(CFCSocialUser)
members = MembersStructuredProperty(CFCSocialUser, repeated=True)
@staticmethod
def create_group(name):
"""Create a new group"""
group = CFCSocialGroup(name=name)
group.members = []
return group
def add_member(self, social_user):
"""Add a member to the local group"""
if self.contains_user(social_user):
raise Exception('Duplicate user detected')
else:
self.members.append(social_user)
def contains_user(self, social_user):
"""Checks if user is a member of the given group"""
for user in self.members:
if user.username == social_user.username:
return True
else:
return False
和测试用例
from tests.cfcsocialtests.testbase import CFCTestBase_NDB
from nose.tools import *
from nose.plugins.attrib import attr
from mainsite.rainbow.models.CFCSocialGroup import CFCSocialGroup
from tests.test_CFCSocialUser import create_user
class TestMembersStructuredProperty(CFCTestBase_NDB):
@attr("CRUD")
def test_validation_works(self):
"""Test to see if the validation works on the property"""
group = CFCSocialGroup.create_group('Group1')
user = create_user()
group.members = [user]
group.put()
案例无法执行并出现以下错误
vinay$ nosetests -v test_membersStructuredProperty.py
Test to see if the validation works on the property ... ERROR
======================================================================
ERROR: Test to see if the validation works on the property
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/vinay/App-Engine/Rainbow/cfc-social-media-website/tests/test_membersStructuredProperty.py", line 14, in test_validation_works
group.members = [user]
File "/Users/vinay/google-cloud-sdk/platform/google_appengine/google/appengine/ext/ndb/model.py", line 1400, in __set__
self._set_value(entity, value)
File "/Users/vinay/google-cloud-sdk/platform/google_appengine/google/appengine/ext/ndb/model.py", line 1142, in _set_value
value = [self._do_validate(v) for v in value]
File "/Users/vinay/google-cloud-sdk/platform/google_appengine/google/appengine/ext/ndb/model.py", line 1092, in _do_validate
value = self._call_shallow_validation(value)
File "/Users/vinay/google-cloud-sdk/platform/google_appengine/google/appengine/ext/ndb/model.py", line 1284, in _call_shallow_validation
return call(value)
File "/Users/vinay/google-cloud-sdk/platform/google_appengine/google/appengine/ext/ndb/model.py", line 1331, in call
newvalue = method(self, value)
File "/Users/vinay/App-Engine/Rainbow/cfc-social-media-website/mainsite/rainbow/models/properties/CFCMembersStructuredProperty.py", line 6, in _validate
if value in self:
TypeError: argument of type 'MembersStructuredProperty' is not iterable
答案 0 :(得分:1)
_validate(),... 不需要处理:
- ...
- 重复值:基础结构负责为重复值中的每个列表项调用_from_base_type()或_to_base_type()。
这不是在重复字段中对项目进行验证的地方。相反,这应该在模型验证中完成。