मैं Django में एक DateTimeField की तारीख कैसे फ़िल्टर कर सकता हूं?


173

मैं DateTimeFieldएक तिथि के साथ तुलना को फ़िल्टर करने का प्रयास कर रहा हूं । मेरा मतलब:

MyObject.objects.filter(datetime_attr=datetime.date(2009,8,22))

मुझे उत्तर के रूप में एक खाली क्वेरी सूची मिलती है क्योंकि (मुझे लगता है) मैं समय पर विचार नहीं कर रहा हूं, लेकिन मैं "किसी भी समय" चाहता हूं।

क्या ऐसा करने के लिए Django में एक आसान तरीका है?

मेरे पास डेटटाइम में बस गया समय है, यह नहीं है 00:00


5
यह Django की परेशानियों में से एक है। यह एक सरल और सामान्य उपयोग मामला है, इसे प्राप्त करने का कोई सरल तरीका नहीं है।
9

जवाबों:


114

इस तरह के लुकअप django.views.generic.date_basedको निम्न प्रकार से कार्यान्वित किया जाता है:

{'date_time_field__range': (datetime.datetime.combine(date, datetime.time.min),
                            datetime.datetime.combine(date, datetime.time.max))} 

क्योंकि यह काफी क्रियात्मक है, __dateऑपरेटर के उपयोग से वाक्य रचना में सुधार करने की योजना है । अधिक विवरणों के लिए " # 9596 किसी दिनांक समय सीमा की तुलना में बहुत कठिन है " की जाँच करें।


4
रेंज के साथ प्रयोग करना: Q(created__gte=datetime.combine(created_value, time.min))
डिंगो

10
ऐसा लगता है कि यह Django 1.9 में
उतरेगा

14
Django 1.9 में नया:Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
गैर

102
YourModel.objects.filter(datetime_published__year='2008', 
                         datetime_published__month='03', 
                         datetime_published__day='27')

// टिप्पणियों के बाद संपादित करें

YourModel.objects.filter(datetime_published=datetime(2008, 03, 27))

doest काम नहीं करता है क्योंकि यह 0 से सेट समय मानों के साथ एक डेटाइम ऑब्जेक्ट बनाता है, इसलिए डेटाबेस में समय मेल नहीं खाता है।


जवाब के लिए thx! पहला विकल्प डेटाटाइमफिल्ड के साथ काम नहीं करता है। दूसरा वैकल्पिक काम करता है;)। यदि कोई अन्य विधि जानता है तो कृपया जवाब दें
Xidobix

डेटाटाइम मॉड्यूल (मिनट), मिनट्स, सेकंड्स का उपयोग करके docs.python.org/library/datetime.html#datetime-objects सेकंड सुरक्षित है। दूसरा एक काम कर रहे प्रोजेक्ट से है, जिसकी जगह var हैं, आप डॉक्स में देख सकते हैं कि यह सही है
zalew

मुझे पता है कि यह वैकल्पिक है, समस्या यह है कि मेरे
डेटाइमफील्ड

"पहला विकल्प डेटाटाइमफिल्ड्स के साथ काम नहीं करता है।" यह बहुत आश्चर्यजनक होगा, क्योंकि datetime.datetime () एक datetime ऑब्जेक्ट djangoproject.com/documentation/0.96/models/basic मॉडल की परिभाषा और उदाहरणों की जांच करता है: pub_date = मॉडल .ateTimeield () pub_date = datetime (2005, 7, 7) 30)
zalew

"मुझे पता है कि यह वैकल्पिक है, समस्या यह है कि मेरे डेटाइमफील्ड का समय व्यवस्थित हो गया है, यह 00:00 नहीं है" ओह, अब मैं इसे देखता हूं। हां, बिना समय तर्क के यह 00 पर सेट हो जाता है, इसलिए यह वापस नहीं आता है :)
zalew

88

यहाँ परिणाम हैं जो मुझे ipython के टाइमिट फंक्शन के साथ मिले हैं:

from datetime import date
today = date.today()

timeit[Model.objects.filter(date_created__year=today.year, date_created__month=today.month, date_created__day=today.day)]
1000 loops, best of 3: 652 us per loop

timeit[Model.objects.filter(date_created__gte=today)]
1000 loops, best of 3: 631 us per loop

timeit[Model.objects.filter(date_created__startswith=today)]
1000 loops, best of 3: 541 us per loop

timeit[Model.objects.filter(date_created__contains=today)]
1000 loops, best of 3: 536 us per loop

इसमें तेजी दिखाई देती है।


यह समाधान सबसे हाल ही में लगता है। मुझे आश्चर्य है कि इसे 4 अपवोट्स मिले हैं, क्योंकि जब मैं containsसमाधान का प्रयास करता हूं, तो मुझे त्रुटि संदेश मिलता है:Unable to get repr for <class 'django.db.models.query.QuerySet'>
होउमन

मैं आज परिणामों की पुन: जाँच और अद्यतन करता हूं और मुझे नहीं लगता कि आपकी त्रुटि __containsफ़िल्टर के कारण हुई है । लेकिन अगर आप उन मुद्दों में भाग ले रहे हैं जो आपको django डॉक्स उदाहरण का उपयोग करना चाहिए __gte
मोरेनो

4
__Contains विधि मेरे लिए ठीक काम करती है। मुझे लगता है कि यह संभवतः सबसे अच्छा जवाब है क्योंकि यह प्रदर्शन तुलना प्रदान करता है। मैंने एक से अधिक मतदान किया है, लेकिन मुझे आश्चर्य है कि इसमें अधिक बदलाव नहीं हैं।
रोबॉटहैंस

मुझे startswithसमाधान पसंद है ..
w411 3

46

अब Django के पास __date क्वेरीसेट फ़िल्टर है जो विकास संस्करण में दिनांक के विरुद्ध डेटाटाइम ऑब्जेक्ट्स को क्वेरी करने के लिए है। इस प्रकार, यह जल्द ही 1.9 में उपलब्ध होगा।



सबसे अच्छा जवाब, नए Django संस्करणों के लिए मान्य है
serfer2

यह मेरे लिए काम नहीं करता है, पता नहीं क्यों :( मैं django पर हूँ। 1.11 मेरा सटीक अपवाद है: NotImforceedError: subatasses of basedatabaseoperations के लिए एक datetime_cast_date () विधि की आवश्यकता हो सकती है
AbdurRehman Khan

44
Mymodel.objects.filter(date_time_field__contains=datetime.date(1986, 7, 28))

ऊपर मैंने जो प्रयोग किया है। न केवल यह काम करता है, इसमें कुछ अंतर्निहित तार्किक समर्थन भी है।


3
यहाँ अन्य सभी उत्तरों से बहुत बेहतर, धन्यवाद!
परिजन

sssss-Shazam! 💯
डीपीएस

30

Django 1.9 के रूप में, ऐसा करने का तरीका __dateडेटाटाइम ऑब्जेक्ट पर उपयोग करके है ।

उदाहरण के लिए: MyObject.objects.filter(datetime_attr__date=datetime.date(2009,8,22))


27

यह __year, __month, और __day का उपयोग करने के समान परिणाम देता है और मेरे लिए काम करता है:

YourModel.objects.filter(your_datetime_field__startswith=datetime.date(2009,8,22))

19
ऐसा प्रतीत होता है कि यह दिनांक ऑब्जेक्ट को स्ट्रिंग में बदल देता है और तारीखों की एक स्ट्रिंग तुलना करता है इसलिए db को एक पूर्ण तालिका स्कैन करने के लिए मजबूर करता है। बड़ी तालिकाओं के लिए यह आपके प्रदर्शन को मार देता है
yilmazhuseyin

8

active_on मान लेना एक दिनांक ऑब्जेक्ट है, इसे 1 दिन बढ़ाएँ फिर सीमा करें

next_day = active_on + datetime.timedelta(1)
queryset = queryset.filter(date_created__range=(active_on, next_day) )

2

यहाँ एक दिलचस्प तकनीक है- मैंने केवल तारीख के माध्यम से एक डेटाइम को देखने के परिणाम को प्राप्त करने के लिए MySQL पर Django के साथ लागू की गई शुरुआती प्रक्रिया का लाभ उठाया। असल में, जब Django डेटाबेस में लुकअप करता है तो उसे DATETIME MySQL स्टोरेज ऑब्जेक्ट के लिए एक स्ट्रिंग रूपांतरण करना होता है, इसलिए आप उस पर फ़िल्टर कर सकते हैं, तारीख का टाइमस्टैम्प भाग छोड़कर - इस तरह%% केवल दिनांक से मेल खाता है ऑब्जेक्ट और आपको दी गई तारीख के लिए हर टाइमस्टैम्प मिलेगा।

datetime_filter = datetime(2009, 8, 22) 
MyObject.objects.filter(datetime_attr__startswith=datetime_filter.date())

यह निम्नलिखित प्रश्न का प्रदर्शन करेगा:

SELECT (values) FROM myapp_my_object \ 
WHERE myapp_my_object.datetime_attr LIKE BINARY 2009-08-22%

इस मामले में LIKE BINARY तिथि के लिए सब कुछ मैच करेगा, टाइमस्टैम्प कोई फर्क नहीं पड़ता। सहित मान:

+---------------------+
| datetime_attr       |
+---------------------+
| 2009-08-22 11:05:08 |
+---------------------+

उम्मीद है कि यह सबको मदद करता है जब तक कि Django समाधान के साथ बाहर नहीं आता है!


ठीक है, तो यह ऊपर mhost और kettlehell के रूप में एक ही जवाब प्रतीत होता है, लेकिन बैकएंड में क्या हो रहा है, इसके अधिक विवरण के साथ। कम से कम आपके पास डेटटाइम () की डेट डेट () विशेषता के साथ-साथ उपयोग करने या शुरू करने का एक कारण है!
bbengfort

2

यहाँ एक शानदार ब्लॉगपोस्ट है जो इसे कवर करता है: Django ORM में तुलनात्मक तिथियां और डेटाटाइम

Django> 1.7, <1.9 के लिए सबसे अच्छा समाधान एक परिवर्तन को पंजीकृत करना है:

from django.db import models

class MySQLDatetimeDate(models.Transform):
    """
    This implements a custom SQL lookup when using `__date` with datetimes.
    To enable filtering on datetimes that fall on a given date, import
    this transform and register it with the DateTimeField.
    """
    lookup_name = 'date'

    def as_sql(self, compiler, connection):
        lhs, params = compiler.compile(self.lhs)
        return 'DATE({})'.format(lhs), params

    @property
    def output_field(self):
        return models.DateField()

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

Foo.objects.filter(created_on__date=date)

संपादित करें

यह समाधान निश्चित रूप से बैक एंड डिपेंडेंट है। लेख से:

बेशक, यह कार्यान्वयन DATE () फ़ंक्शन वाले SQL के आपके विशेष स्वाद पर निर्भर करता है। MySQL करता है। तो SQLite करता है। दूसरी ओर, मैंने व्यक्तिगत रूप से PostgreSQL के साथ काम नहीं किया है, लेकिन कुछ googling मुझे विश्वास दिलाता है कि इसमें DATE () फ़ंक्शन नहीं है। तो एक कार्यान्वयन यह सरल लगता है कि यह कुछ हद तक बैकेंड-निर्भर होगा।


क्या यह MySQL विशिष्ट है? वर्ग के नाम की पसंद के बारे में सोचकर।
बिन्नोज डेविड

@BinojDavid हाँ, यह बैकेंड आश्रित है
Dan Gayle

मैंने इसे Django 1.8 और PostgreSQL 9.6.6 का उपयोग करके परीक्षण किया और यह पूरी तरह से काम करता है। वास्तव में PostgreSQL का उपयोग करके आप इस वाक्यविन्यास का उपयोग भी कर सकते हैं:return '{}::date'.format(lhs), params
michal-michalak

1

हम्म .. मेरा समाधान काम कर रहा है:

Mymodel.objects.filter(date_time_field__startswith=datetime.datetime(1986, 7, 28))


0

Django में 1.7.6 कार्य:

MyObject.objects.filter(datetime_attr__startswith=datetime.date(2009,8,22))

2
यह केवल तभी काम करता है जब आप सटीक तारीख की तलाश में हों, आप __lteउदाहरण के लिए उपयोग नहीं कर सकते ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.