我正在使用Tastypie以及以下资源和Django Tutorial的相同模型。
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。 / p>
我做错了什么?
答案 0 :(得分:0)
您正在呼叫get_list
过滤一次而不是get_detail
此外,get_detail
不会通过`question_id'过滤pk,请参见此处: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的方式。