子类重复属性不可迭代

时间:2016-05-06 10:04:51

标签: python google-app-engine

继续previous question

背景

我想确保无法在同一个用户中添加相同的用户。

结构化子类属性代码(包含用户集合的属性)是

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

1 个答案:

答案 0 :(得分:1)

documentation州:

  

_validate(),... 需要处理:

     
      
  • ...
  •   
  • 重复值:基础结构负责为重复值中的每个列表项调用_from_base_type()或_to_base_type()。
  •   

这不是在重复字段中对项目进行验证的地方。相反,这应该在模型验证中完成。