2011-10-17 27 views
6

câu hỏi đầu tiên của tôi ở đây:Sử dụng tài nguyên tastypie theo quan điểm

Vì vậy, tôi đang sử dụng tastypie có api cho ứng dụng của tôi.

Tôi muốn có thể sử dụng ngon để hiển thị json và sau đó bao gồm điều đó trong chế độ xem django để tôi có thể khởi động dữ liệu của ứng dụng.

Có một ví dụ về điều này trong django sách dạy nấu ăn tastypie đây: http://django-tastypie.readthedocs.org/en/latest/cookbook.html#using-your-resource-in-regular-views

Vấn đề là tôi KHÔNG THỂ được điều này để làm việc, tôi đã cố gắng biến thể từ đơn giản đến phức tạp hơn và tôi chỉ không thể có được nó, ở đây một số mã cho mô hình của tôi:

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="") 
    [...] 

và các nguồn lực của tôi:

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, 
     } 

và chỉ số quan điểm của tôi:

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)) 

Những gì tôi muốn là renderOne() chức năng của tôi để cho tôi json của ONE ChatMessageResource Và tôi cũng muốn một hàm renderAll() để gice tôi TẤT CẢ (hoặc lọc) ChatMessageResources trong json.

Và tôi muốn sử dụng internals tastypie, tôi biết tôi có thể serialize nó bằng bản thân mình nhưng đó không phải là điểm ..

Ngay bây giờ các lỗi là:

NoReverseMatch at /live/ 

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

Tôi chỉ nhận được điên , Tôi đã cố gắng hàng giờ rồi.

Vì vậy, xin vui lòng, làm thế nào để có được một/TẤT CẢ tài nguyên như JSON bằng mã bằng cách sử dụng ngon trong một chế độ xem django!

Nếu Nó không rõ ràng hay tôi cần phải làm rõ, xin vui lòng chỉ cần hỏi, nhờ

Thật là những gì tôi muốn làm là để có thể có được công JSON được trả về bởi một url API tôi tạo ra, nhưng từ mã, không bằng cách truy cập url .. Vì vậy, nếu tôi có /api/v1/messages/?chat_session=14 trả về danh sách thư, tôi muốn có thể thực hiện tương tự bằng mã (chứ không phải bằng cách tìm nạp url có curl hoặc một cái gì đó vui lòng).

Lưu ý: định nghĩa của ModelResource.obj_get từ 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).") 

Trả lời

9

Vì vậy, ở đây tôi tìm thấy giải pháp, vấn đề là với url giải quyết ... Tôi cần thêm

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

đến đối tượng có liên quan (phiên ở đây) để cho nó làm việc (đừng hỏi tại sao!)

Vì vậy, đây là giải pháp làm việc của tôi cho renderDetail và 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 

Và đây là một cách sử dụng ví dụ:

cmr = ChatMessageResource() 

dataOne= cmr.renderDetail("723") 

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

Tôi biết tôi có thể bỏ qua việc tạo ra yêu cầu và tạo ra phản ứng nhưng tôi nghĩ rằng đây là dễ dàng hơn – dwarfy

+4

Một cách sạch hơn để làm điều này sẽ là chỉ định tên API khi đảo ngược URL, ví dụ: 'url = reverse ('api_dispatch_list', kwargs = {'resource_name': 'myresource', 'api_name': 'v1'})'. Điều này có nghĩa là mã sẽ tiếp tục hoạt động nếu bạn thay đổi URL hoặc số phiên bản gốc của API. –

+0

ok cảm ơn, tôi sẽ cố gắng ... – dwarfy

0

Vấn đề của bạn có vẻ là ở đây:

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

Các thông số để obj_get nên kwargs có thể được truyền trực tiếp đến một tiêu chuẩn get. None không nên ở trong đó.

+0

tôi đã cố gắng mà không có nó, nhưng nó không thay đổi .. Dù sao tôi đặt các nguồn ModelResource.obj_get trên – dwarfy

2

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

Tôi đã phát hiện ra rằng obj_get phương thức cần có một đối tượng được yêu cầu . Xem liên kết.

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) 
    .... 
Các vấn đề liên quan