2009-12-18 17 views
20

कहें कि मेरे पास सृजन तिथि द्वारा आदेशित फ़ोटो की एक सूची है, निम्नानुसार:Django ORM का उपयोग कर पिछले/अगले आइटम को पाने का कोई चालाक तरीका है?

class Photo(models.Model): 
    title = models.Char() 
    image = models.Image() 
    created = models.DateTimeField(auto_now_add=True) 

    class Meta: 
     ordering = ('-created',) 

मेरे पास एक मनमाने ढंग से फोटो ऑब्जेक्ट photo_x है। क्या क्वेरीसेट में स्थिति के अनुसार पिछले और अगली तस्वीरों को ढूंढने का कोई आसान तरीका है? साथ ही, अगर मैं शुरुआत/अंत में हूं तो मैं चारों ओर लपेटना चाहूंगा और अगर यह केवल 1 या 2 फोटो हैं तो यह विफल नहीं होगा।

उत्तर

32

आप भाग्यशाली हैं! Django get_next_by_foo और get_previous_by_fooDateField & DateTimeField के लिए डिफ़ॉल्ट रूप से विधियों को बनाता है जब तक उनके पास null=True नहीं है।

उदाहरण के लिए:

>>> from foo.models import Request 
>>> r = Request.objects.get(id=1) 
>>> r.get_next_by_created() 
<Request: xyz246> 

और अगर आप एक सेट के अंत तक पहुँचते यह एक DoesNotExist अपवाद है, जो आप आसानी से सेट की शुरुआत करने के लिए वापस जाने के लिए एक ट्रिगर के रूप में इस्तेमाल कर सकते हैं बढ़ा देंगे:

>>> r2 = r.get_next_by_created() 
>>> r2.get_next_by_created() 
... 
DoesNotExist: Request matching query does not exist. 

अतिरिक्त पठन: Extra instance methods

+0

धन्यवाद, मुझे कुछ ऐसा पता था जैसे मैं अस्तित्व में था, मैं बस इसके बारे में सोच नहीं पाया। –

+0

मुझे खुशी है कि यह वही था जो आप खोज रहे थे। मदद करने में सक्षम होने के लिए खुशी हुई। – jathanism

0
jathanism जवाब, अपने उपयोगी करने के लिए

, लेकिन get_next_by_FOO और get_previous_by_FOO मिलीसेकेंड की अनदेखी ... उदाहरण के लिए यह पाश में बनाया वस्तुओं के लिए काम नहीं करेगा:

for i in range(100): 
    Photo.objects.create(title='bla', ...) 

obj = Photo.objects.first() 
obj.get_previous_by_created() 

DoesNotExist: Photo matching query does not exist. 
2

get_next_by_foo और get_previous_by_foo आसान है, लेकिन बहुत ही सीमित हैं - वे आपकी मदद नहीं करते हैं तो आप ऑर्डर दे रहे हैं एक से अधिक फ़ील्ड, या एक गैर-दिनांक फ़ील्ड पर।

मैंने django-next-prev को एक ही विचार के अधिक सामान्य कार्यान्वयन के रूप में लिखा था। आपके मामले में आप सिर्फ ऐसा कर सकता है, क्योंकि आप अपने मेटा में आदेश निर्धारित किया है:

from next_prev import next_in_order, prev_in_order 
from .models import Photo 

photo = Photo.objects.get(...) 
next = next_in_order(photo) 
prev = prev_in_order(photo) 

यदि आप क्षेत्रों के कुछ अन्य संयोजन पर ऑर्डर करने के लिए, बस क्वेरीसमूह पारित चाहता था:

photos = Photo.objects.order_by('title') 
photo = photos.get(...) 
next = next_in_order(photo, qs=photos) 
+1

पैकेज बहुत अच्छा काम करता है, साझा करने के लिए धन्यवाद। – DragonBobZ

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