2015-01-15 55 views
0

我正在使用Tastypie以下資源和Django教程的相同模型。正確設置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_list過濾一次發生,而不是get_detail 此外,get_detail不過濾通過的PK`question_id',在這裏看到:https://github.com/toastdriven/django-tastypie/blob/master/tastypie/resources.py#L1303

雖然,你爲什麼不使用tastypie實際的網址嗎? 按照食譜(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,這是更RESTful方式。

+0

我想使用嵌套版本(用於學習目的),因爲它將在未來的項目中更有用。另外,'get_detail'不能用作一個'Question'可以有多個'Choice',就像python教程一樣。另外,對於格式,我正在使用教程中的'.format'。 – LawfulHacker 2015-01-16 22:49:31