在视图中使用 tastypie 资源

发布于 2024-12-10 09:06:20 字数 4797 浏览 0 评论 0原文

我的第一个问题:

所以我正在使用 tastypie 为我的应用程序提供 api。

我希望能够使用 tastypie 渲染 json,然后将其包含在 django 视图中,以便我可以引导我的应用程序的数据。

django tastypie 食谱中有一个示例: http://django-tastypie.readthedocs.org/en/latest/cookbook.html#using-your-resource-in-regular-views

问题是我无法让它工作,我尝试了从更简单到更复杂的变体,但我无法得到它,这里是我的模型的一些代码:

class ChatMessage(models.Model):
     content = models.TextField()
     added = models.DateTimeField(auto_now_add=True)

     author = models.ForeignKey(ChatUser, related_name="messages")
     chat_session = models.ForeignKey(ChatSession, related_name="messages")
     answer_to = models.ForeignKey('self', blank=True, null=True)

     flagged = models.BooleanField(blank=True,default=False)
     mododeleted = models.BooleanField(blank=True,default=False)
     mododeleted_by = models.ForeignKey(ChatUser,blank=True,null=True,default=None)
     mododeleted_at = models.DateTimeField(blank=True,null=True,default=None)
     [...]

class ChatSession (models.Model):
    title = models.CharField(max_length=200)
    link_title = models.CharField(max_length=200)
    description = tinymce_models.HTMLField()
    date = models.DateTimeField()
    online = models.BooleanField(default=False)
    next_session = models.BooleanField(default=False)
    meps = models.ManyToManyField(ChatMep)
    uid_newsupdate = models.CharField(max_length=200,blank=True,null=True,default="")
    [...]

和我的资源:

class ChatMessageResource(MyModelResource):
    chat_session = fields.ForeignKey(ChatSessionResource, 'chat_session')

    def renderOne(self,request,pkval):
       data =  self.obj_get(None,pk=pkval)
       dbundle = self.build_bundle(obj=data,request=request)
       return self.serialize(None,self.full_dehydrate(dbundle),'application/json')

    def dehydrate(self, bundle):
        bundle.data['likes'] = bundle.obj.get_likes()
        bundle.data['likes_count'] = len(bundle.data['likes'])
        return bundle

    class Meta:
        authentication = Authentication()
        authorization = Authorization()
        queryset = ChatMessage.objects.all()
        resource_name = 'message'
        fields = ('content', 'added', 'flagged', 'mododeleted','author','answer_to','chat_session')
        filtering = {
            'chat_session': ALL_WITH_RELATIONS,
        }

以及我的视图索引:

def index(request):

    cur_sess = get_current_chat_session()

    data1= ChatMessageResource().renderOne(request,723)

    return render_to_response('test.html',
                          { 
                            'all_data' : data1 
                           },
                          context_instance=RequestContext(request))

我想要的是我的 renderOne() 函数给我 ONE ChatMessageResource 的 json 而且我还想要一个 renderAll() 函数来给我 json 中的所有(或过滤后的)ChatMessageResources。

我想使用tastypie内部结构,我知道我可以自己序列化它,但这不是重点..

现在的错误是:

NoReverseMatch at /live/

Reverse for 'api_dispatch_detail' with arguments '()' and keyword arguments '{'pk': 14L, 'resource_name': 'session'}' not found.

我只是变得疯狂,我已经尝试了几个小时。

那么,如何在 django 视图中使用 tastypie 通过代码获取一个/所有 JSON 资源!

如果不清楚或者我需要澄清,请询问,谢谢。

我真正想做的是能够获取我创建的 API url 返回的 JSON,但是从代码中,而不是通过访问 url ..所以如果我有 /api/v1/messages/?chat_session=14 它返回消息列表,我希望能够通过代码执行相同的操作(而不是通过使用curl或其他方式获取url )。

笔记 : ModelResource.obj_get 的定义来自 https://github.com/toastdriven/django-tastypie/ blob/master/tastypie/resources.py

def obj_get(self, request=None, **kwargs):
            """
    A ORM-specific implementation of ``obj_get``.

    Takes optional ``kwargs``, which are used to narrow the query to find
    the instance.
    """
            try:
                base_object_list = self.get_object_list(request).filter(**kwargs)
                object_list = self.apply_authorization_limits(request, base_object_list)
                stringified_kwargs = ', '.join(["%s=%s" % (k, v) for k, v in kwargs.items()])

                if len(object_list) <= 0:
                    raise self._meta.object_class.DoesNotExist("Couldn't find an instance of '%s' which matched '%s'." % (self._meta.object_class.__name__, stringified_kwargs))
                elif len(object_list) > 1:
                    raise MultipleObjectsReturned("More than '%s' matched '%s'." % (self._meta.object_class.__name__, stringified_kwargs))

                return object_list[0]
            except ValueError:
                raise NotFound("Invalid resource lookup data provided (mismatched type).")

my first question here :

So I'm using tastypie to have api's for my app.

I want to be able to use tastypie to render json and then include that in a django view so that I can bootstrap my app's data.

There is an example of this in django tastypie cookbook here : http://django-tastypie.readthedocs.org/en/latest/cookbook.html#using-your-resource-in-regular-views

The problem is that I CANNOT get this to work, I've tried variants from simpler to more complex and I just cant get it, here some code for my models :

class ChatMessage(models.Model):
     content = models.TextField()
     added = models.DateTimeField(auto_now_add=True)

     author = models.ForeignKey(ChatUser, related_name="messages")
     chat_session = models.ForeignKey(ChatSession, related_name="messages")
     answer_to = models.ForeignKey('self', blank=True, null=True)

     flagged = models.BooleanField(blank=True,default=False)
     mododeleted = models.BooleanField(blank=True,default=False)
     mododeleted_by = models.ForeignKey(ChatUser,blank=True,null=True,default=None)
     mododeleted_at = models.DateTimeField(blank=True,null=True,default=None)
     [...]

class ChatSession (models.Model):
    title = models.CharField(max_length=200)
    link_title = models.CharField(max_length=200)
    description = tinymce_models.HTMLField()
    date = models.DateTimeField()
    online = models.BooleanField(default=False)
    next_session = models.BooleanField(default=False)
    meps = models.ManyToManyField(ChatMep)
    uid_newsupdate = models.CharField(max_length=200,blank=True,null=True,default="")
    [...]

and my resources :

class ChatMessageResource(MyModelResource):
    chat_session = fields.ForeignKey(ChatSessionResource, 'chat_session')

    def renderOne(self,request,pkval):
       data =  self.obj_get(None,pk=pkval)
       dbundle = self.build_bundle(obj=data,request=request)
       return self.serialize(None,self.full_dehydrate(dbundle),'application/json')

    def dehydrate(self, bundle):
        bundle.data['likes'] = bundle.obj.get_likes()
        bundle.data['likes_count'] = len(bundle.data['likes'])
        return bundle

    class Meta:
        authentication = Authentication()
        authorization = Authorization()
        queryset = ChatMessage.objects.all()
        resource_name = 'message'
        fields = ('content', 'added', 'flagged', 'mododeleted','author','answer_to','chat_session')
        filtering = {
            'chat_session': ALL_WITH_RELATIONS,
        }

and my view index :

def index(request):

    cur_sess = get_current_chat_session()

    data1= ChatMessageResource().renderOne(request,723)

    return render_to_response('test.html',
                          { 
                            'all_data' : data1 
                           },
                          context_instance=RequestContext(request))

What I want is my renderOne() function to give me the json of ONE ChatMessageResource
And also I'd like a renderAll() function to gice me ALL (or filtered) ChatMessageResources in json.

And I want to use tastypie internals, I KNOW i could serialize it by myself but that's not the point..

Right now the error is :

NoReverseMatch at /live/

Reverse for 'api_dispatch_detail' with arguments '()' and keyword arguments '{'pk': 14L, 'resource_name': 'session'}' not found.

I'm just getting crazy, I've been trying for hours.

So please, how to get ONE/ALL resource as JSON by code using tastypie in a django view !

If It's not clear or I need to clarify, please just ask, thanks

Really what I want to do is to be able to get the JSON returned by an API url I created, but from code, not by visiting the url .. So If I have /api/v1/messages/?chat_session=14 which return a list of messages, I want to be able to do the same by code (and not by fetching the url with curl or something please).

Note :
definition of ModelResource.obj_get from https://github.com/toastdriven/django-tastypie/blob/master/tastypie/resources.py

def obj_get(self, request=None, **kwargs):
            """
    A ORM-specific implementation of ``obj_get``.

    Takes optional ``kwargs``, which are used to narrow the query to find
    the instance.
    """
            try:
                base_object_list = self.get_object_list(request).filter(**kwargs)
                object_list = self.apply_authorization_limits(request, base_object_list)
                stringified_kwargs = ', '.join(["%s=%s" % (k, v) for k, v in kwargs.items()])

                if len(object_list) <= 0:
                    raise self._meta.object_class.DoesNotExist("Couldn't find an instance of '%s' which matched '%s'." % (self._meta.object_class.__name__, stringified_kwargs))
                elif len(object_list) > 1:
                    raise MultipleObjectsReturned("More than '%s' matched '%s'." % (self._meta.object_class.__name__, stringified_kwargs))

                return object_list[0]
            except ValueError:
                raise NotFound("Invalid resource lookup data provided (mismatched type).")

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一指流沙 2024-12-17 09:06:20

所以在这里我找到了解决方案,问题在于 url 解析...我需要添加

def get_resource_uri(self, bundle_or_obj):
   return '/api/v1/%s/%s/' % (self._meta.resource_name,bundle_or_obj.obj.id)

到相关对象(此处的会话)才能使其工作(不要问为什么!)

所以这是我的 renderDetail 工作解决方案和 renderList :

def renderDetail(self,pkval):
    request = HttpRequest()
    request.GET = {'format': 'json'}
    resp =  self.get_detail(request, pk=pkval)
    return resp.content


def renderList(self,options={}):
    request = HttpRequest()
    request.GET = {'format': 'json'}
    if len(options) > 0:
        request.GET.update(options)

    resp = self.get_list(request)
    return resp.content

这是一个示例用法:

cmr = ChatMessageResource()

dataOne= cmr.renderDetail("723")

dataAll = cmr.renderList({'limit':'0','chat_session':cur_sess.pk})

So here I found the solution, the problem was with url resolving ... I needed to add

def get_resource_uri(self, bundle_or_obj):
   return '/api/v1/%s/%s/' % (self._meta.resource_name,bundle_or_obj.obj.id)

to the related object (session here) in order for it to work (don't ask why!)

So here is my working solution for renderDetail and renderList :

def renderDetail(self,pkval):
    request = HttpRequest()
    request.GET = {'format': 'json'}
    resp =  self.get_detail(request, pk=pkval)
    return resp.content


def renderList(self,options={}):
    request = HttpRequest()
    request.GET = {'format': 'json'}
    if len(options) > 0:
        request.GET.update(options)

    resp = self.get_list(request)
    return resp.content

And here is an example usage :

cmr = ChatMessageResource()

dataOne= cmr.renderDetail("723")

dataAll = cmr.renderList({'limit':'0','chat_session':cur_sess.pk})
找回味觉 2024-12-17 09:06:20

https://github.com/toastdriven/django-tastypie/issues/962

我发现 obj_get 方法需要捆绑的 request 对象。请参阅链接。

def user_detail(request, username):
    ur = UserResource()
    # Add this request bundle to the obj_get() method as shown.
    req_bundle = ur.build_bundle(request=request)
    user = ur.obj_get(req_bundle, username=username)
    ....

https://github.com/toastdriven/django-tastypie/issues/962

I've found that obj_get method needs a bundled request object. See the link.

def user_detail(request, username):
    ur = UserResource()
    # Add this request bundle to the obj_get() method as shown.
    req_bundle = ur.build_bundle(request=request)
    user = ur.obj_get(req_bundle, username=username)
    ....
清醇 2024-12-17 09:06:20

您的问题似乎在这里:

data =  self.obj_get(None,pk=pkval)

obj_get 的参数应该是可以直接传递给标准 get 的 kwargs。 None 不应该在那里。

Your problem seems to be here:

data =  self.obj_get(None,pk=pkval)

The parameters to obj_get should be kwargs that can be passed directly to a standard get. None should not be in there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文