2012-06-30 2 views
1

tastypie api를 통해 아이템을 저장할 때 문제가 발생합니다. (POST 메서드)Django Tastypie, ManyToMany Saving Error

여기 내 api.py 코드입니다.

from tastypie.resources import ModelResource, ALL, ALL_WITH_RELATIONS 
from tastypie.authorization import DjangoAuthorization 
from tastypie.authentication import BasicAuthentication 
from tastypie import fields 
from apps.clients.models import Client 
from django.contrib.auth.models import User 

class ClientAPI(ModelResource): 
    users = fields.ToManyField('apps.clients.api.ClientUserAPI', 'users',related_name='entry',full=True) 


    class Meta: 
     queryset = Client.objects.all() 
     resource_name="clients" 
     authentication = BasicAuthentication() 
     authorization = DjangoAuthorization() 
     filtering={ 
      "users":ALL 
     } 

    def hydrate_m2m(self,bundle): 
     if bundle.data.get("users"): 
      for user_id in bundle.data["users"]: 
       new_user = User.objects.get(id=user_id) 
       bundle.obj.users.add(new_user) 


class ClientUserAPI(ModelResource): 
    class Meta: 
     queryset = User.objects.all() 
     resource_name = 'users' 
     fields = ['username', 'first_name', 'last_name', 'last_login'] 
     authentication = BasicAuthentication() 
     authorization = DjangoAuthorization() 

메신저 POST 데이터의 경우 저장에 성공했지만 오류가 발생합니다.

{"error_message": "'NoneType' object has no attribute 'obj'", "traceback": "Traceback (most recent call last):\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 192, in wrapper\n response = callback(request, *args, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 397, in dispatch_list\n return self.dispatch('list', request, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 427, in dispatch\n response = method(request, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1165, in post_list\n updated_bundle = self.obj_create(bundle, request=request, **self.remove_api_resource_names(kwargs))\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1784, in obj_create\n self.save_m2m(m2m_bundle)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1942, in save_m2m\n related_mngr = getattr(bundle.obj, field_object.attribute)\n\nAttributeError: 'NoneType' object has no attribute 'obj'\n"} 

내가 hydrate_m2m에 "반환 번들"줄을 추가있을 때, M2M 절약이 성공적으로 (공백)없는, 여전히 같은 나에게 오류를 제공합니다.

{"error_message": "'str' object has no attribute 'obj'", "traceback": "Traceback (most recent call last):\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 192, in wrapper\n response = callback(request, *args, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 397, in dispatch_list\n return self.dispatch('list', request, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 427, in dispatch\n response = method(request, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1165, in post_list\n updated_bundle = self.obj_create(bundle, request=request, **self.remove_api_resource_names(kwargs))\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1784, in obj_create\n self.save_m2m(m2m_bundle)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1951, in save_m2m\n related_bundle.obj.save()\n\nAttributeError: 'str' object has no attribute 'obj'\n"} 

것은 내가 오류를 반환하는 것은, 코드에서 hydrate_m2m 삭제있을 때 :

{"error_message": "The URL provided '1' was not a link to a valid resource.", "traceback": "Traceback (most recent call last):\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 192, in wrapper\n response = callback(request, *args, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 397, in dispatch_list\n return self.dispatch('list', request, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 427, in dispatch\n response = method(request, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1165, in post_list\n updated_bundle = self.obj_create(bundle, request=request, **self.remove_api_resource_names(kwargs))\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1783, in obj_create\n m2m_bundle = self.hydrate_m2m(bundle)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 743, in hydrate_m2m\n bundle.data[field_name] = field_object.hydrate_m2m(bundle)\n\n File \"/Library/Python/2.7/site-packages/tastypie/fields.py\", line 742, in hydrate_m2m\n m2m_hydrated.append(self.build_related_resource(value, **kwargs))\n\n File \"/Library/Python/2.7/site-packages/tastypie/fields.py\", line 588, in build_related_resource\n return self.resource_from_uri(self.fk_resource, value, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/fields.py\", line 522, in resource_from_uri\n obj = fk_resource.get_via_uri(uri, request=request)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 636, in get_via_uri\n raise NotFound(\"The URL provided '%s' was not a link to a valid resource.\" % uri)\n\nNotFound: The URL provided '1' was not a link to a valid resource.\n"} 

내가 URL이 제공 한 생각 "1"사용자 ID입니다.

말해주십시오. 뭐가 잘못 됐니?

btw, 영어를 잘 모릅니다. 죄송합니다.

+0

당신이 POST의 바르가 무엇인지에 추가 할 수 있습니다 제안 카슨 등 int 찬성 제거 람다 :

def hydrate_users(self, bundle): try: user_ids = map(int, bundle.data.get('users', [])) except ValueError: raise BadRequest("User ids must be ints") # from tastypie.exceptions bundle.data['users'] = User.objects.filter(id__in=user_ids) return bundle 

희망이

편집을하는 데 도움이 모델에 데이터를 전달하는보기의 관련 부분은 무엇입니까 – Alvin

답변

7

나는 쉼표로 구분 된 ID로 사용자 자원을 게시하고 있음을 확신합니다. tastypie가 기본적으로 관련 리소스를 처리하는 방식이 아닙니다. '/ api/v1/users/1'과 같은 관련 리소스를 가리키는 URL 목록을 게시해야합니다.

또는 hydrate_m2m을 hydrate_users로 변경할 수 있습니다. 일반 hydrate_m2m은 리소스의 모든 필드를 반복하고 url-string에서 관련 리소스의 인스턴스로 변환하려고 시도합니다 (이 때문에 "제공된 URL"에 대한 오류가 발생합니다). hydrate_users의 코드는 다음과 같습니다

+0

당신은 남자입니다! – Anakin

+3

'map (int, bundle.data.get ('users', []))'도 작동합니다. 당신에게 람다를 저장합니다. – Carson