2009-05-27 11 views
5

मॉडल 'दर्ज' में एक डेटाटाइम फ़ील्ड है। मैं डेटा को सभी प्रविष्टियों को खोजने के लिए क्वेरी करना चाहता हूं, जहां दोपहर (start_time) और 5:00 बजे (end_time) के बीच बनाया गया है।मैं समय-समय पर फ़ील्ड में समय-समय पर फ़िल्टर कैसे करूं?

selected = Entry.objects.filter(entered__gte=start_time, entered__lte=end_time) 

(के रूप में मैं उम्मीद) मैं की कोई त्रुटि मिलती है:

"ValidationError: Enter a valid date/time in YYYY-MM-DD HH:MM[:ss[.uuuuuu]] format." 

तो मैं जानता हूँ कि मैं __year उपयोग कर सकते हैं तो मैं कोशिश की।

selected = Entry.objects.filter(entered__time__gte=start_time, entered__time__lte=end_time) 

मैं की कोई त्रुटि मिलती है:

"FieldError: Join on field 'start' not permitted. Did you misspell 'time' for the lookup type?" 

उत्तर

2

इसके बजाय आप डाटाबेस के तंत्र का उपयोग कर अजगर में फ़िल्टर कर सकते हैं:

for e in Entry.objects.all(): 
    if i.entered.hour>= 9 and i.entered.hour < 17 :# or break down to minutes/seconds 
     list.append(e) 

लेकिन दोनों समाधान बदसूरत हैं, मुझे लगता है।

स्टीव, आप तय करने के लिए है, क्या आप के लिए कम बदसूरत है:

  • एक के लिए लूप में डेटा का एक बहुत processsing,
  • या .extra (..) और गुजर द्वारा उपयोग ORM-प्रणाली
+0

इस पल के रूप में यह विकल्प मैं पसंद करता हूं। मुझे अभी भी एक बेहतर विकल्प चाहिए। –

+2

django में घंटे/मिनट पर फ़िल्टर करना संभव होगा 1.8: https://docs.djangoproject.com/en/1.8/ref/models/querysets/#hour Entry.objects.filter (enter__hour__gte = 9, enter__hour__lte = 17) – imposeren

+0

दुर्भाग्यवश, Django 1.8 में यह संभव नहीं है। आप केवल सटीक घंटे के मिलान के लिए फ़िल्टर कर सकते हैं: 'Entry.objects.filter (enter__hour = 9) ' –

5

मैं नहीं मानता कि वहाँ में निर्मित इस के लिए समर्थन है, लेकिन आप पास कर सकते हैं extra where-clause मानकों (चेतावनी: डीबी पर निर्भर व्यवहार शुरू करने की कुछ संभावना यहाँ)।

उदाहरण के लिए, पर Postgres, कुछ की तरह:

Entry.objects.extra(where=['EXTRACT(hour from entered) >= 12 and '\ 
        'EXTRACT(hour from entered) < 17']) 

आप संभावित रूप से असुरक्षित इनपुट उपयोग कर रहे हैं मानों 12 और 17 निर्धारित करने के लिए, ध्यान दें कि आप भी अतिरिक्त है कि यह सुनिश्चित करेंगे करने के लिए एक पैरामीटर विकल्प निर्दिष्ट कर सकते हैं उचित उद्धरण और भागना, और उसके बाद अपने कथन में मानक एसक्यूएल %s प्लेसहोल्डर्स का उपयोग करें।

+1

मैं बस के बारे में उन पंक्तियों के साथ कुछ पोस्ट किया गया था। SQLite का उपयोग करना, 'Entry.objects.extra (जहां = ["समय (दर्ज) '12: 00' और '17: 00 '"] के बीच)]' वही करना चाहिए। – Arnaud

+0

बेशक आप कस्टम वर्ग के बिना समय सीमा के लिए पूछ सकते हैं। मेरा उत्तर – vikingosegundo

0

क्या आपने start_time और end_time के लिए datetime objects प्रदान किया था?

एक त्वरित कोशिश-आउट:

class Entry(models.Model): 
    entered = models.DateTimeField() 

>>> from datetime import datetime 
>>> Entry(entered = datetime.now()).save() 
>>> Entry.objects.filter(entered__lte = datetime.now()) 
[<Entry: Entry object>] 
>>> Entry.objects.filter(entered__gte = datetime.now()) 
[] 
>>> Entry.objects.filter(entered__gte = datetime.now(), entered__lte=datetime(2009,11,1,0,0)) 
[<Entry: Entry object>] 
+1

हां देखें, लेकिन आप वास्तव में इस सवाल का जवाब नहीं देते हैं: यह 12:00 और 7 बजे के बीच किए गए हर प्रविष्टि को वापस करना है, इससे कोई फर्क नहीं पड़ता कि क्या तारीख है। – Arnaud

+1

और मैं केवल उस समय तक फ़िल्टर नहीं करना चाहता हूं जब समय 12:34:54 से 14:23:06 हो सकता है, महत्वपूर्ण बात यह है कि फ़िल्टर केवल समय पर विचार करता है और तारीख नहीं। –

+0

मुझे डर है कि 'अतिरिक्त()' संशोधक का उपयोग करना एकमात्र विकल्प है। स्टीवन, आप किस डीबी बैकएंड का उपयोग कर रहे हैं? – Arnaud

3

एक उदाहरण के रूप SQLite का उपयोग करना, एक अपेक्षाकृत स्वच्छ और सामान्य समाधान होगा:

Entry.objects.extra(where=["time(entered) between '%s' and '%s'"], 
        params=[start_time.strftime("%H:%M"), end_time.strftime("%H:%M")]) 
+0

प्रश्न को गलत तरीके से पढ़ा है इस समाधान में मुझे छोटी सी बग है जिसने मुझे आधे घंटे तक संघर्ष किया: आपको उद्धरणों में '% s' डालने की आवश्यकता नहीं है, इसलिए यह% s और% के बीच समय (दर्ज) होना चाहिए s "'। कम से कम यह है कि आज 2015 में चीजें कैसे हैं। इसके अलावा, 'अतिरिक्त() 'अब बहिष्कृत है और वे [RawSql] का उपयोग करने का सुझाव देते हैं (https://docs.djangoproject.com/en/1.8/ref/models/expressions/ इसके बजाय # django.db.models.expressions.RawSQL)। –

0

मैं फिल्टर x<=arg सुझाव है और x>=arg2 शामिल नहीं है।

-2

आप बीच में फ़िल्टर करने के लिए रेंज का उपयोग कर सकते हैं। मुझे यह फ़िल्टर करने का सबसे अच्छा तरीका मिला क्योंकि एसक्यूएल Django से बेहतर फ़िल्टरिंग करता है।

fromRange=datetime.datetime.strptime(request.GET.get('from'),'%Y-%m-%dT%H:%M:%S.%fZ') 
toRange=datetime.datetime.strptime(request.GET.get('to'),'%Y-%m-%dT%H:%M:%S.%fZ') 

entry = Entry.objects.filter(entryTime__range=(fromRange,toRange)) 
0

मैं सिर्फ एक समान उपयोग के मामले के लिए एक समाधान पता लगा - शायद किसी को इस उपयोगी पाता है:

मेरे मामले में, मेरे पास है उपलब्धता और बाधा मॉडल इतना (सरलीकृत) की तरह:

class Availability(...): 
    start = models.DateTimeField() 
    end = models.DateTimeField() 

class Constraint(...): 
    from = models.TimeField() 
    to = models.TimeField() 

मैं उन लाभों को ढूंढना चाहता था जो किसी भी बाधा का उल्लंघन नहीं करते हैं। ::time साथ

Availability.objects.extra(
    where=['NOT (start::time, "end"::time) OVERLAPS (\'{0}\'::time, \'{1}\'::time)'.format(
     from.strftime("%H:%M"), to.strftime("%H:%M") 
    )] 
) 

नोट कैसे आप (Postgres मामले में या बल्कि timestamptime without timezone करने के लिए) DateTime को Time डाल सकता है और फिर OVERLAPS का उपयोग समय सीमाओं की तुलना करने के लिए:

Postgres के साथ, यह मेरे लिए काम किया।

और मूल प्रश्न के संबंध में, आप भी कर सकते हैं:

Availability.objects.extra(
    where=['start::time BETWEEN \'{0}\'::time AND \'{1}\'::time AND 
      "end"::time BETWEEN \'{0}\'::time AND \'{1}\'::time'.format(
     from.strftime("%H:%M"), to.strftime("%H:%M") 
    )] 
) 
संबंधित मुद्दे