2015-01-15 4 views
0

다음 리소스와 Django 자습서와 동일한 모델에서 Tastypie를 사용하고 있습니다.Tastypie에서 중첩 된 리소스에 대한 올바른 집합

from django.conf.urls import url 
from django.views.decorators.csrf import csrf_exempt 

from tastypie import fields 
from tastypie.constants import ALL, ALL_WITH_RELATIONS 
from tastypie.resources import ModelResource 
from tastypie.utils import trailing_slash 

from .models import Question, Choice 


class ChoiceResource(ModelResource): 
    class Meta: 
     queryset = Choice.objects.all() 
     resource_name = 'choice' 

    def prepend_urls(self): 
     return [ 
      url(r"^(?P<resource_name>%s)\.(?P<format>\w+)$" % self._meta.resource_name, self.wrap_view('dispatch_list'), name="api_dispatch_list"), 
      url(r"^(?P<resource_name>%s)/schema\.(?P<format>\w+)$" % self._meta.resource_name, self.wrap_view('get_schema'), name="api_get_schema"), 
      url(r"^(?P<resource_name>%s)/set/(?P<pk_list>\w[\w/;-]*)\.(?P<format>\w+)$" % self._meta.resource_name, self.wrap_view('get_multiple'), name="api_get_multiple"), 
      url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)\.(?P<format>\w+)$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"), 
     ] 

    def determine_format(self, request): 
     """ 
     Used to determine the desired format from the request.format 
     attribute. 
     """ 
     if (hasattr(request, 'format') and 
       request.format in self._meta.serializer.formats): 
      return self._meta.serializer.get_mime_for_format(request.format) 
     return super(ChoiceResource, self).determine_format(request) 

    def wrap_view(self, view): 
     @csrf_exempt 
     def wrapper(request, *args, **kwargs): 
      request.format = kwargs.pop('format', None) 
      wrapped_view = super(ChoiceResource, self).wrap_view(view) 
      return wrapped_view(request, *args, **kwargs) 
     return wrapper 


class QuestionResource(ModelResource): 
    class Meta: 
     queryset = Question.objects.all() 
     resource_name = 'question' 

    choices = fields.ToManyField(ChoiceResource, 'choices') 

    def prepend_urls(self): 
     return [ 
      url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/choices\.(?P<format>\w+)$" % self._meta.resource_name, self.wrap_view('get_choices'), name="api_get_choices"), 
      url(r"^(?P<resource_name>%s)\.(?P<format>\w+)$" % self._meta.resource_name, self.wrap_view('dispatch_list'), name="api_dispatch_list"), 
      url(r"^(?P<resource_name>%s)/schema\.(?P<format>\w+)$" % self._meta.resource_name, self.wrap_view('get_schema'), name="api_get_schema"), 
      url(r"^(?P<resource_name>%s)/set/(?P<pk_list>\w[\w/;-]*)\.(?P<format>\w+)$" % self._meta.resource_name, self.wrap_view('get_multiple'), name="api_get_multiple"), 
      url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)\.(?P<format>\w+)$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"), 
     ] 

    def determine_format(self, request): 
     if (hasattr(request, 'format') and 
       request.format in self._meta.serializer.formats): 
      return self._meta.serializer.get_mime_for_format(request.format) 
     return super(QuestionResource, self).determine_format(request) 

    def wrap_view(self, view): 
     @csrf_exempt 
     def wrapper(request, *args, **kwargs): 
      request.format = kwargs.pop('format', None) 
      wrapped_view = super(QuestionResource, self).wrap_view(view) 
      return wrapped_view(request, *args, **kwargs) 
     return wrapper 

    def get_choices(self, request, **kwargs): 
     try: 
      bundle = self.build_bundle(data={'pk': kwargs['pk']}, request=request) 
      obj = self.cached_obj_get(bundle=bundle, **self.remove_api_resource_names(kwargs)) 
     except ObjectDoesNotExist: 
      return HttpGone() 
     except MultipleObjectsReturned: 
      return HttpMultipleChoices("More than one resource is found at this URI.") 

     choice_resource = ChoiceResource() 
     return choice_resource.get_list(request, question_id=obj.pk) 

내가 /api/v1/question.json를 요청하면 내가 /api/v1/question/1.json를 들어, 같은 예상대로 모든 질문을 얻을하지만 /api/v1/question/1/choices.json를 요청할 때 나는 모든 선택을 얻을뿐만 아니라 질문 1.

의 사람들은 내가 무슨 일을하고있는 중이 야 ?

답변

0

당신은 또한, get_detail가로 PK를 필터링하지 않는 대신 get_detail 중 하나 명 발생을 필터링 할 get_list를 호출`question_id' 여기를 참조 : 비록 https://github.com/toastdriven/django-tastypie/blob/master/tastypie/resources.py#L1303

을, 당신은 tastypie의 실제 URL을 사용 해달라고 이유는 무엇입니까? 요리 책 (http://django-tastypie.readthedocs.org/en/latest/cookbook.html)에 따르면, 당신은이처럼 자원을 만듭니다

class QuestionResource(ModelResource): 
    class Meta: 
     queryset = Question.objects.all() 
     resource_name = 'question' 
     serializer = Serializer(formats=['json', 'xml', 'html']) 

그런 다음, 더 편안하고 방법 인 /api/v1/question/1/?format=xml를 호출 할 수 있습니다.

+0

미래의 프로젝트에서 더 유용 할 것이므로 중첩 된 버전을 학습용으로 사용하고 싶습니다. 또한,'get_detail'은 파이썬 튜토리얼처럼'Question'가 여러 개의'Choice'를 가질 수 있기 때문에 사용할 수 없습니다. 또한 형식에 대해서는 튜토리얼에서와 같이'.format'을 사용하고있었습니다. – LawfulHacker

관련 문제