How to “POST” ndb.StructuredProperty?

北慕城南 提交于 2019-12-23 04:29:56

问题


Problem:

I have following EndpointsModels,

class Role(EndpointsModel):
    label = ndb.StringProperty()
    level = ndb.IntegerProperty()

class Application(EndpointsModel):
    created = ndb.DateTimeProperty(auto_now_add=True)
    name = ndb.StringProperty()
    roles = ndb.StructuredProperty(Role, repeated=True)

and an API method:

class ApplicationApi(protorpc.remote.Service):
    @Application.method(http_method="POST",
                        request_fields=('name', 'roles'),
                        name="create",
                        path="applications")
    def ApplicationAdd(self, instance):
        return instance

When I try to POST this data:

{ "name": "test", "roles": [{ "label": "test", "level": 0 }] }

I'm getting an error ( trace ):

AttributeError: 'Role' object has no attribute '_Message__decoded_fields'

Workaround:

I tried to use EndpointsAliasProperty:

class ApplicationApi(protorpc.remote.Service):
    ...
    def roless_set(self, value):
        logging.info(value)
        self.roles = DEFAULT_ROLES

    @EndpointsAliasProperty(setter=roless_set)
    def roless(self):
        return getattr(self, 'roles', [])

which results in 400 BadRequest

Error parsing ProtoRPC request (Unable to parse request content: Expected type <type 'unicode'> for field roless, found {u'level': 0, u'label': u'test'} (type <type 'dict'>))

If I add property_type to the alias:

    @EndpointsAliasProperty(setter=roless_set, property_type=Role)

I'm getting server error again ( trace ):

TypeError: Property field must be either a subclass of a simple ProtoRPC field, a ProtoRPC enum class or a ProtoRPC message class. Received Role<label=StringProperty('label'), level=IntegerProperty('level')>.

Is there a way to "convert" EndpointsModel to ProtoRPC message class? Are there any better solutions for creating models with StructuredProperty using POST data? I couldn't find any examples for this, if someone knows any links, please share (:

UPDATE:

After some digging through source code, I found EndpointsModel.ProtoModel() that can be used to convert ndb.Model to ProtoRPC message class

    @EndpointsAliasProperty(setter=roless_set, property_type=Role.ProtoModel())

This resolves issue with EndpointsAliasProperty workaround, but the problem remains...


回答1:


Check this repo: https://github.com/zdenulo/epd-error-example. Here I was demonstrating error in endpoints-proto-datastore which in latest version should be fixed. So upgrade in repository to latest endpoints-proto-datastore and you should have working example which similar to what you want to achieve.




回答2:


Hey Sasxa has there been a fix for this as far as you know? I am currently dealing with the same issue, and I can start a new thread for this discussion if nothing has been found.

Update: created a new issue linked to this one

Update: This issue has been resolved! You can check out the issue here.



来源:https://stackoverflow.com/questions/35673294/how-to-post-ndb-structuredproperty

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!