2014-03-25 6 views
4

우리는 API 구현을 위해 Flask-Restful을 사용하고 있습니다. 데이터베이스로서 MongoDB와 MongoEngine을 ODM으로 사용합니다. MongoEngine이 Restful과 함께 일하게하려면 this blog article을 따라갔습니다. 올바른 json 형식을 얻으려면 내장 marsheling-methods을 사용합니다. 이는 하나의 객체 (예 : 컬렉션의 한 항목)를 완벽하게 처리하지만 객체 목록 (예 : 컬렉션의 모든 항목)을 마살 (marsheling)하면 AttributeError이 발생합니다 (단 하나의 객체와 동일한 구문을 사용하지만). 이것은 우리 모델과 우리의 견해가 어떻게 생겼는지를 보여줍니다. (나는 그것들을 별도의 파일과 작업으로 붙여 넣지 않습니다.)컬렉션의 개체 목록에 대한 특성 오류가 있습니까?

모델 :

class Task(db.Document): 
    name = db.StringField() 
    description_mini = db.StringField() 

전망 :

parser = reqparse.RequestParser() 
parser.add_argument('task_id', type=str) 

task_format = { 
    "name": fields.String, 
    "description_mini": fields.String 
} 

class TasksView(Resource): 

    @marshal_with(task_format) 
    def get(self): 
     tasks = Task.objects().all() 
     return tasks, 200 


class TaskDetailView(Resource): 

    @marshal_with(task_format) 
    def get(self): 
     args = parser.parse_args() 
     startup_id = args['task_id'] 

     task = Task.objects(id=task_id).first() 

     return task, 200 

전체 스택 트레이스 :

AttributeError 

Traceback (most recent call last) 
File "/project/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__ 
return self.wsgi_app(environ, start_response) 
File "/project/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app 
response = self.make_response(self.handle_exception(e)) 
File "/project/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 257, in error_router 
return self.handle_error(e) 
File "/project/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app 
response = self.full_dispatch_request() 
File "/project/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request 
rv = self.handle_user_exception(e) 
File "/project/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 257, in error_router 
return self.handle_error(e) 
File "/project/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request 
rv = self.dispatch_request() 
File "/project/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request 
return self.view_functions[rule.endpoint](**req.view_args) 
File "/project/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 397, in wrapper 
resp = resource(*args, **kwargs) 
File "/project/venv/lib/python2.7/site-packages/flask/views.py", line 84, in view 
return self.dispatch_request(*args, **kwargs) 
File "/project/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 487, in dispatch_request 
resp = meth(*args, **kwargs) 
File "/project/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 562, in wrapper 
return marshal(data, self.fields), code, headers 
File "/project/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 533, in marshal 
return OrderedDict(items) 
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/collections.py", line 52, in __init__ 
self.__update(*args, **kwds) 
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_abcoll.py", line 547, in update 
for key, value in other: 
File "/project/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 532, in <genexpr> 
for k, v in fields.items()) 
File "/project/venv/lib/python2.7/site-packages/flask_restful/fields.py", line 104, in output 
value = get_value(key if self.attribute is None else self.attribute, obj) 
File "/project/venv/lib/python2.7/site-packages/flask_restful/fields.py", line 37, in get_value 
return _get_value_for_keys(key.split('.'), obj, default) 
File "/project/venv/lib/python2.7/site-packages/flask_restful/fields.py", line 42, in _get_value_for_keys 
return _get_value_for_key(keys[0], obj, default) 
File "/project/venv/lib/python2.7/site-packages/flask_restful/fields.py", line 51, in _get_value_for_key 
return obj[key] 
File "/project/venv/lib/python2.7/site-packages/mongoengine/queryset/base.py", line 152, in __getitem__ 
raise AttributeError 
AttributeError 
+0

전체 역 추적은 무엇입니까? 'AttributeError'가 발생한 곳과 어떤 속성을 가지고 있지 않은지 알지 못해도 도움이되지 않습니다. – dirn

+0

수정 사항을 참조하십시오! 감사합니다 – Tronic

답변

6

당신이뿐만 아니라 목록으로 필드를 정의해야 목록을 마샬링 할 .

내가이 일을 생각 :

task_list_format = { 
    'tasks': fields.List(fields.Nested(task_format)) 
} 

class TasksView(Resource): 

    @marshal_with(task_list_format) 
    def get(self): 
     tasks = Task.objects().all() 
     return { 'tasks': tasks }, 200 

나는 플라스크-의 RESTful의 마샬링 지원을 사용하여 일반 목록을 반환 할 수 없습니다 생각, 그것은 항상 사전은 기대하고있다. 그런 이유로 저는 목록을 "작업"키 아래에 두었습니다.

이 정보가 도움이되기를 바랍니다.

+0

여러 작업 목록을 보내는 테스트를 작성한다면 어떻게 될까요? 이 접근법은 목록의 첫 번째 객체 만 마샬링합니다. @Miguel - 어떤 생각? –

+0

잘 모르겠습니다. 이 솔루션은 전체 목록을 마샬링합니다. 목록의 각 항목은 중첩 된 항목으로 처리됩니다. – Miguel

0

flask_restful.marshal_with_fields을 시도 :

>>> from flask_restful import marshal_with_field, fields 
>>> @marshal_with_field(fields.List(fields.Integer)) 
... def get(): 
...  return ['1', 2, 3.0] 
... 
>>> get() 
[1, 2, 3]