लगता है कि Django डेटा कैशिंग कैसा लगता है। अब ()

मेरे पास ऐसा मॉडल है जो इस तरह दिखता है:

class Item(models.Model):
    ...
    publish_date = models.DateTimeField(default=datetime.datetime.now)
    ...

और एक प्रबंधक जो इस तरह दिखता है:

from datetime import datetime

class ItemManager(Manager):
    def published(self):
        return self.get_query_set().filter(publish_date__lte=datetime.now()

और एक ऐसा दृश्य जो इस तरह दिखता है:

class ItemArchive(ArchiveIndexView):
    queryset = Item.objects.published()
    date_field = 'publish_date'

विचार यह है कि मैं Item.objects.published() को कॉल कर सकता हूं और सभी प्रकाशित आइटम की क्वेरीसेट प्राप्त कर सकता हूं।

समस्या यह है कि जब Django सर्वर प्रारंभ होता है और फिर उस मान को कैश करता है तो मैनेजर में डेटाटाइम .now() कॉल निष्पादित करता प्रतीत होता है। तो अगर आज 24 मई है, और मैंने 23 मई की प्रकाशित तिथि के साथ एक <�कोड> आइटम </कोड> बनाया है, और 22 मई को सर्वर शुरू किया है, तो 23 मई आइटम ItemArchive </कोड> देखें। जैसे ही मैं अपाचे को पुनरारंभ करता हूं, 23 मई की वस्तु सही तरीके से दिखाई देती है।

मैं Django को datetime.now() निष्पादित करने के लिए मजबूर कैसे कर सकता हूं जब प्रबंधक को बुलाया जाता है?

0
जोड़ा
विचारों: 1

3 उत्तर

queryset क्लास चर का उपयोग न करें, और इसके बजाय get_queryset ओवरराइड करें। आम तौर पर, मुझे लगता है कि queryset एक लाल हेरिंग का थोड़ा सा है। यदि आप इसके बजाय बस मॉडल निर्दिष्ट करते हैं, तो Django स्वचालित रूप से क्वेरी को self.model.objects.all() पर सेट करता है। यदि आपको किसी भी फ़िल्टरिंग की आवश्यकता है, तो 100 में से 99 बार आपको थ्रेड-सुरक्षित होने के लिए get_queryset ओवरराइड करना होगा। इसके बजाए निम्नलिखित आज़माएं।

class ItemArchive(ArchiveIndexView):
    model = Item
    date_field = 'publish_date'

    def get_queryset(self):
        return super(ItemArchive, self).get_queryset().published()
0
जोड़ा

मेरा मानना ​​है कि यह आपके दृश्य को queryset = Item.objects.published() को एक वर्ग चर के रूप में परिभाषित करने के कारण होता है। यह लाइन एक बार निष्पादित की जाएगी, जब आपका ItemArchive क्लास प्रारंभ में आयात किया जाता है। आपको उस लाइन को उस विधि में ले जाना चाहिए जहां प्रत्येक बार दृश्य को बुलाया जाएगा।

0
जोड़ा
आप दोनों के लिए धन्यवाद! यह मुझे थोड़ा झुकाव ले गया, लेकिन दोनों समाधान समझ में आता है। मुझे लगता है कि मेरे संदर्भ में डीजीएल अधिक उपयुक्त है।
जोड़ा लेखक user1272534, स्रोत
हाँ। या, एक अलग प्रकाशित प्रबंधक को परिभाषित करें, जो get_query_set को ओवरराइड करता है। यह आलसी होगा, जबकि आपका प्रकाशित विधि नहीं है।
जोड़ा लेखक Daniel Roseman, स्रोत
यह निश्चित रूप से काम करेगा। सबसे अच्छी तकनीक संदर्भ पर निर्भर करेगी। यदि यह वास्तव में क्लास वैरिएबल के रूप में queryset होने का एहसास है, तो डैनियल का सुझाव सबसे अच्छा होगा। हालांकि, यदि आप वर्तमान में queryset का उपयोग कर रहे हैं, तो आप सीधे Item.objects.published() को कॉल करते हैं, तो आपका कोड अधिक पठनीय हो सकता है।
जोड़ा लेखक dgel, स्रोत

First, just use models.DateTimeField(auto_now_add=True)

संपादित:

दूसरा, get_queryset विधि का उपयोग करें:

class ItemArchive(ArchiveIndexView):
    date_field = 'publish_date'

    def get_queryset(self):
        return Item.objects.published()
0
जोड़ा
मैं auto_now_add का उपयोग नहीं करना चाहता क्योंकि मैं उपयोगकर्ताओं को प्रकाशन तिथि संपादित करने का विकल्प देना चाहता हूं। ओवरराइटिंग get_queryset वह है जो उसके उत्तर में डीजीएल सुझाया गया है। मुझे लगता है कि यह समाधान है। धन्यवाद!
जोड़ा लेखक user1272534, स्रोत