Django

2011-05-12 9 views
5

के साथ स्टेटिक फ़ाइल वर्जनिंग मैं अपने सीएसएस/जावास्क्रिप्ट के लिए दूर-भविष्य की हेडर्स की अवधि समाप्त कर रहा हूं ताकि ब्राउज़र कैश किए जाने के बाद कभी भी फाइलों के लिए कभी भी पूछ न सके। मेरे पास एक साधारण वर्जनिंग तंत्र भी है ताकि अगर फाइलें बदल जाएंगी, तो ग्राहक जान जाएंगे।Django

मूल रूप से मैं एक टेम्पलेट टैग है और मैं की तरह

<script type="text/javascript" src="{{ MEDIA_URL }}{% versioned "javascript/c/c.js" %}"></script>

जो कुछ

<script type="text/javascript" src="http://x.com/media/javascript/c/c.min.js?123456"></script> हो जाएगा है।

टेम्पलेट टैग एक फ़ाइल javascript/c/c.js.v खोलता है जहां इसे संस्करण संख्या मिलती है और इसे क्वेरी स्ट्रिंग में जोड़ती है। संस्करण एक शेल स्क्रिप्ट द्वारा उत्पन्न होता है (मैन्युअल रूप से अब के लिए चलाएं, शायद पूर्व-प्रतिबद्ध हुक जोड़ देगा) जो जांचता है कि फ़ाइल बदल गई है (git diff का उपयोग करके)।

यह वह जगह है सब ठीक काम कर रहा है, सिवाय:

मैं छवियों के लिए संस्करण का एक ही प्रकार के रूप में अच्छी तरह से लागू करना चाहते हैं। लेकिन छवियों को सीएसएस से संदर्भित किया जा सकता है - जो एक स्थिर फ़ाइल है (nginx द्वारा परोसा जाता है) - इसलिए वहां कोई टेम्पलेट टैग नहीं है।

फ़ाइल संस्करण के लिए बेहतर तरीका क्या है?

वैकल्पिक रूप से, मैं टेम्पलेट टैग को एक मिडलवेयर के साथ बदलने के बारे में सोच रहा हूं जो प्रतिक्रिया वापस करने से पहले सभी लिंक बदलता है। यह टेम्पलेट टैग से बेहतर है, जिसे गलती से छोड़ा जा सकता है। लेकिन अभी भी सीएसएस से संदर्भित छवियों के मुद्दे को हल नहीं करता है।

इसके अलावा, मुझे पता है कि क्वेरी स्ट्रिंग के हिस्से के रूप में संस्करण होने से फ़ाइल को कैशिंग नहीं करने वाले कुछ प्रॉक्सी के साथ समस्या हो सकती है - इसलिए मैं फ़ाइल नाम का संस्करण भाग बनाने पर विचार करता हूं - उदाहरण के लिए javascript/c/c.123456.js

नोट: ऐसा लगता है कि Django का उपयोग करके इस समस्या को हल करने का कोई तरीका नहीं है (जाहिर है - क्योंकि मैं Django के माध्यम से सीएसएस की सेवा भी नहीं करता)। लेकिन वहां एक समाधान होना चाहिए, शायद कुछ nginx चाल शामिल है।

+1

नीचे @paluh द्वारा उत्तर आपकी सबसे अच्छी शर्त है। Django में फ़ाइल से फ़ाइल mtimes खींचना Django में फ़ाइलों पर सीधे mtimes की जांच करने पर आपको कुछ भी बचा नहीं रहा है। यह केवल जटिलता की एक अतिरिक्त परत और विफलता का एक और बिंदु जोड़ रहा है (शेल स्क्रिप्ट क्रॉन नौकरी के रूप में चल रहा है)। –

+0

वास्तव में, mtimes मेरा सेटअप आसान बना सकता है - स्क्रिप्ट चलाने और गिट पर निर्भरता को चलाने की आवश्यकता को कम करता है। मैं आमतौर पर mtimes पर भरोसा नहीं करता (वे किसी अन्य फाइल सिस्टम की प्रतिलिपि बनाते समय बदल सकते हैं, या बैक अप ले सकते हैं, या ...) - लेकिन इस मामले में मुझे लगता है कि यह वास्तव में कोई फर्क नहीं पड़ता, क्योंकि स्रोत पेड़ हमेशा एक ही स्थान पर होता है । इसके अलावा, अगर माइटिम्स वास्तव में कुछ कारणों से बदलते हैं, तो सबसे बुरा होता है कैश अवैध हो जाते हैं। भयानक नहीं – ibz

+1

सीएसएस फ़ाइलों को संसाधित करने के लिए पूर्व-तैनाती चरण के बारे में कैसे? मैंने कुछ ऐसा किया लेकिन Django के साथ नहीं। यह कुछ कस्टम PHP था। –

उत्तर

0

लिंक के साथ सभी सीधा लिंक बदलने के लिए मेरी पूर्व-स्क्रिप्ट स्क्रिप्ट में एक और कदम जोड़ देगा ओ कम से कम सीएसएस में संस्करणित फाइलें।

ऐसा लगता है कि ऐसा करने का कोई बेहतर तरीका नहीं है। यदि आप किसी के बारे में सोचते हैं, तो मुझे बताएं और मैं इसे स्वीकार करने वाले उत्तर के रूप में चिह्नित करने पर विचार करूंगा।

आपकी टिप्पणियों के लिए धन्यवाद!

0

हम इस सरल templatetag उपयोग कर रहे हैं फ़ाइल संशोधन समय के आधार पर संस्करण संख्या उत्पन्न करने के लिए:

@register.simple_tag 
def staticfile(path): 
    file_path = os.path.join(settings.MEDIA_ROOT, path) 
    url = '%s%s?v=%s' % (settings.MEDIA_URL, path, os.stat(file_path)[stat.ST_MTIME]) 
    return url 

उपयोग::

import os 
import posixpath 
import stat 
import urllib 

from django import template 
from django.conf import settings 
from django.contrib.staticfiles import finders 

register = template.Library() 

@register.simple_tag 
def staticfile(path): 
    normalized_path = posixpath.normpath(urllib.unquote(path)).lstrip('/') 
    absolute_path = finders.find(normalized_path) 
    if not absolute_path and getattr(settings, 'STATIC_ROOT', None): 
     absolute_path = os.path.join(settings.STATIC_ROOT, path) 
    if absolute_path: 
     return '%s%s?v=%s' % (settings.STATIC_URL, path, os.stat(absolute_path)[stat.ST_MTIME]) 
    return path 

पूर्व 1.3 Django के लिए इस टैग के भी सरल संस्करण है

<link rel="stylesheet" href="{% staticfile "css/style.css" %}" type="text/css" media="screen" /> 
+0

मेरे मूल समाधान के समान समस्या है। सीएसएस के अंदर संदर्भित छवियों को संभाल नहीं सकते (जब तक मैं Django के माध्यम से सीएसएस की सेवा नहीं करता)। उम्मीद है कि मैं एक बेहतर तरीका पा सकता हूं। – ibz

+0

हां, सीएसएस फाइलों में छवियों को सर्वोत्तम तरीके से कैसे संभालना है इसका सवाल बारहमासी है। आप 'MEDIA_URL' का लाभ नहीं ले सकते हैं और, जैसा कि आपके मामले में है, आप क्वेरी स्ट्रिंग्स या कैशिंग को प्रभावित करने के लिए जोड़ नहीं सकते हैं।यही है, जब तक, आप Django के माध्यम से फ़ाइलों की सेवा नहीं करते हैं, लेकिन यह एक पूरी तरह से अन्य या कीड़े है। –

+0

हालांकि, चूंकि आपका प्रश्न संशोधित फ़ाइलों के लिए कैश को अमान्य करने में से एक है, इसलिए यह अनुमान लगाया जा सकता है कि संशोधित होने पर सीएसएस द्वारा संदर्भित एक छवि सीएसएस फ़ाइल में किसी भी संपादन के अनुरूप होगी। यह जरूरी नहीं है और हमेशा मामला है, लेकिन संभवतः यहां कैश अमान्यता को स्वयं प्रबंधित करना बहुत कठिन नहीं होना चाहिए। –

0

मुझे लगता है कि एक सरल उपाय हो सकता है:

  1. Django टेम्पलेट्स के रूप में लिखें अपने सीएसएस फ़ाइलों।
  2. अपने सीएसएस-टेम्पलेट्स को प्रस्तुत करने के लिए एक Django कमांड लिखें (और उन्हें कहीं भी सुलभ में स्टोर करें)
  3. अपनी परिनियोजन स्क्रिप्ट में यह आदेश कॉल करें।
1

स्टाइल शीट आस्तियों

अपने स्टाइलशीट संदर्भित संपत्ति के लिए, आप बहुत से बेहतर कर रहे हैं सास & कम्पास का उपयोग। कम्पास में एक मिश्रण है जो स्टाइलशीट के संदर्भ में स्थैतिक संपत्तियों के अंत में स्वचालित रूप से संस्करण क्वेरी पैरामीटर जोड़ देगा। जब आप स्टाइलशीट को पुनर्निर्माण करते हैं तो संस्करण संख्या केवल तभी बदलती है (जो स्थानीय रूप से विकसित होने पर compass watch के साथ तुच्छ है)।

खाका आस्तियों

अन्य फ़ाइलों लिए, मैं असल में किसी तरह का है कि एक अजगर मॉड्यूल जिनका एकमात्र उद्देश्य वर्तमान संस्करण को शामिल करने के लिए है पुनर्लेखन के बाद पुल हुक का इस्तेमाल करेगा।

/var/www/aweso.me/ 
    ./files/ 
    ./private-files/ 
    ./static/ 
    ./project/ 
     ./manage.py 
     ./fabfile.py 
     ./.gitignore 
     ./base/ 
      ./__init__.py 
      ./wsgi.py 
      ./settings/ 
       ./__init__.py 
       ./modules 
        ./__init__.py 
        ./users.py 
        ./email.py 
        ./beta.py 
        ./redis.py 
        ./haystack.py 
       ./version.py 
       ./default.py 
       ./local.py 
       ./live.py 

आपका पोस्ट पुल हुक बनाने होगा:

/var/www/aweso.me/project/base/settings/version.py 

कौन होते हैं नवीनतम (या पिछली) Git हैश करने हैं: अपने settings.live में एक साधारण from .version import __version__ as ApplicationVersion साथ फिर

__version__ = "0763j34bf" 

, आपका टेम्पलेट टैग उस क्वेरी पैरामीटर को teh cache buster के रूप में लिखने के लिए बस from settings import ApplicationVersion का उपयोग कर सकता है।