Использование ресурса deliciouspie в представлении

мой первый вопрос здесь:

Поэтому я использую deliciouspie, чтобы иметь API для своего приложения.

Я хочу иметь возможность использовать deliciouspie для рендеринга json, а затем включать его в представление django, чтобы я мог загружать данные своего приложения.

Пример этого есть в поваренной книге вкусных пирогов django здесь: 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() давала мне json ОДНОГО ресурса ChatMessageResource. А также я хотел бы, чтобы функция renderAll() предоставляла мне ВСЕ (или отфильтрованные) ресурсы ChatMessageResources в json.

И я хочу использовать внутренности вкусного пирога, я ЗНАЮ, что могу сериализовать его сам, но это не главное.

Прямо сейчас ошибка:

NoReverseMatch at /live/

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

Я просто схожу с ума, я пытался в течение нескольких часов.

Итак, пожалуйста, как получить ОДИН/ВСЕ ресурсы в виде JSON с помощью кода, используя deliciouspie в представлении django!

Если это неясно или мне нужно уточнить, пожалуйста, просто спросите, спасибо

На самом деле я хочу иметь возможность получить JSON, возвращаемый URL-адресом API, который я создал, но из кода, а не путем посещения URL-адреса. Итак, если у меня есть /api/v1/messages/?chat_session=14, которые возвращают список сообщений, я хочу иметь возможность сделать то же самое с помощью кода (а не путем извлечения 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).")

person dwarfy    schedule 17.10.2011    source источник


Ответы (3)


Итак, здесь я нашел решение, проблема заключалась в разрешении 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})
person dwarfy    schedule 18.10.2011
comment
Я знаю, что могу обойти создание запроса и создание ответа, но я думаю, что это проще - person dwarfy; 18.10.2011
comment
Более чистым способом сделать это было бы указать имя API при изменении URL-адреса, например. url = reverse('api_dispatch_list', kwargs={'resource_name': 'myresource', 'api_name': 'v1'}). Это означает, что код будет продолжать работать, если вы измените корневой URL-адрес API или номер версии. - person Mike Ryan; 26.11.2011

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)
    ....
person user3389572    schedule 16.04.2014

Ваша проблема, кажется, здесь:

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

Параметры obj_get должны быть kwargs, которые могут быть переданы непосредственно стандартному get. None там не должно быть.

person Chris Pratt    schedule 17.10.2011
comment
Пробовал без него, но не меняется.. Все равно выше выложил исходники ModelResource.obj_get - person dwarfy; 17.10.2011