2012-04-20 10 views
8

looking for ideas/alternatives to providing a page/item count/navigation of items matching a GAE datastore query से, मुझे एक संकेत मिलता है कि ऑर्डर देने के द्वारा एक कर्सर के साथ पिछड़ा पृष्ठ नेविगेशन कैसे करें।कर्सर के साथ पिछड़ा पृष्ठांकन काम कर रहा है लेकिन

class CursorTests(test_utils.NDBTest): 

    def testFirst(self): 
    class Bar(model.Model): 
     value = model.IntegerProperty() 

    self.entities = [] 
    for i in range(10): 
     e = Bar(value=i) 
     e.put() 
     self.entities.append(e) 

    q = Bar.query() 
    bars, next_cursor, more = q.order(Bar.key).fetch_page(3) 
    barz, another_cursor, more2 = q.order(-Bar.key).fetch_page(3, start_cursor=next_cursor) 
    self.assertEqual(len(bars), len(barz)) 

दुर्भाग्य से यह इस त्रुटि के साथ विफल रहा।

Traceback (most recent call last): File "/Users/reiot/Documents/Works/appengine-ndb-experiment/ndb/query_test.py", line 32, in testFirst self.assertEqual(len(bars), len(baz)) AssertionError: 3 != 2

हां, सीमा में एक आइटम रिवर्स क्वेरी के साथ गायब है।

bars = [Bar(key=Key('Bar', 1), value=0), Bar(key=Key('Bar', 2), value=1), Bar(key=Key('Bar', 3), value=2)] 
bars = [Bar(key=Key('Bar', 2), value=1), Bar(key=Key('Bar', 1), value=0)] 

मैं इस समस्या को कैसे ठीक कर सकता हूं?

+1

अच्छा सवाल। मैंने इसकी पुष्टि की है। मैंने विशेषज्ञों में बुलाया है। क्या यह उत्पादन डेटास्टोर पर भी इस तरह से व्यवहार करता है? –

उत्तर

14

ठीक है, यहां आधिकारिक उत्तर दिया गया है। आपको कर्सर को "रिवर्स" करने की आवश्यकता है, निम्नानुसार:

rev_cursor = cursor.reversed() 

मुझे यह स्वयं नहीं पता था। :-(मैं यह सुनिश्चित कर दूंगा कि यह fetch_page() के लिए दस्तावेज़ों में दिखाया गया है।

+1

धन्यवाद! इसके लिए आधिकारिक समाधान जानने के लिए अच्छा :-) –

+0

यह है कि मैं साल से दस्तावेज़ीकरण या समाचार में खोज रहा हूं :) – Chameleon

+1

दस्तावेज़ों को लंबे समय से तय किया गया है। Https://developers.google.com/appengine/docs/python/ndb/queries#cursors (उस अनुभाग के अंत की ओर) देखें। –

2

इन एकाधिक कर्सर से निपटने, साथ ही आगे और विपरीत प्रश्न न केवल जटिल हैं, लेकिन सीधे पेजिंग (पृष्ठ पर जाने की अनुमति नहीं देता है) 7), पेज के निचले हिस्से में पृष्ठ लिंक के एक सेट के साथ "< < 1 2 3 4 5 >>", क्योंकि आपको पता नहीं है कि कितने पेज होंगे।

इसी कारण से, मेरा समाधान पूरे परिणाम सेट, या कम से कम एक महत्वपूर्ण परिणाम सेट लाने के लिए होगा, उदाहरण के लिए 10 पृष्ठों के अनुरूप, फिर पृष्ठों को संभालने के लिए सरल डिवीजन करना। एनडीबी बैंडविड्थ (और लागत) को बर्बाद न करने के लिए, आप पहले परिणाम प्राप्त करेंगे keys_only=True के साथ। आपके द्वारा निर्धारित सेट निर्धारित करने के बाद आर वर्तमान पृष्ठ, आप अपनी इकाइयों पर key.get() करते हैं। और यदि आप चाहते हैं कि आप कुछ मिनटों के लिए memcache में चाबियों की पूरी सूची को सहेजने पर विचार कर सकते हैं तो क्वेरी फिर से नहीं चलती है, हालांकि मुझे अब तक यह आवश्यक नहीं मिला है।

def generic_list_paging(objects, page, page_size=10): 
    nb_items = len(objects) 
    item_start = min(page * page_size, nb_items) 
    item_end = min((page + 1) * page_size, nb_items) 
    page_max = (nb_items - 1) // page_size + 1 
    objects = objects[item_start: item_end] 
    paging = {'page': page, 'page_max': page_max} 
    return objects, paging 

अंत में, यदि आप एक generic_list_paging समारोह है कि पेजिंग डिवीजनों करता है और परिणाम सेट के भीतर उचित sublist निकालने के उपयोग

def session_list(): 
    page = request.args.get('page', 0, type=int) 

    sessions_keys = Session.query().order(-Session.time_opened).fetch(100, keys_only=True) 
    sessions_keys, paging = generic_list_paging(sessions_keys, page) 
    sessions = ndb.get_multi(sessions_keys) 

    return render_template('generic_list.html', objects=sessions, paging=paging) 

यह बना रहा है:

यह एक उदाहरण दिया गया है Jinja2 का उपयोग कर रहे हैं, यहां paging का उपयोग कर पेजिंग नेविगेशन है:

{% if paging.page_max > 1 %} 
     <nav> 
      <ul class="pagination"> 
       {% if paging.page > 0 %} 
        <li> 
         <a href="{{ request.path }}?page={{ paging.page-1 }} aria-label="Previous"> 
          <span aria-hidden="true">&laquo;</span> 
         </a> 
        </li> 
       {% endif %} 
       {% for page in range(0,paging.page_max) %} 
        <li {% if page==paging.page %}class="disabled"{% endif %}><a href="{{ request.path }}?page={{ page }}">{{ page+1 }}</a></li> 
       {% endfor %} 
       {% if paging.page < paging.page_max-1 %} 
        <li> 
         <a href="{{ request.path }}?page={{ paging.page+1 }}" aria-label="Next"> 
          <span aria-hidden="true">&raquo;</span> 
         </a> 
        </li> 
       {% endif %} 
      </ul> 
     </nav> 
{% endif %} 
+0

उपरोक्त कोड में, सत्र = [sk.get() सत्र_की में sk के लिए] प्रदर्शन के संदर्भ में अच्छा नहीं है, यह get_multi() होना चाहिए। मैंने बस इसे ठीक किया। – patb

संबंधित मुद्दे