Django

2010-10-28 16 views
14

में कॉन्स्टेंट को परिभाषित करना मैं Django प्रोजेक्ट्स में कुछ स्थिरांक रखना चाहता हूं। उदाहरण के लिए, मान लें कि निरंतर MIN_TIME_TEST कहा जाता है।Django

मैं इस स्थिति को दो स्थानों पर एक्सेस करने में सक्षम होना चाहता हूं: मेरे पायथन कोड के भीतर से, और किसी भी टेम्पलेट के भीतर से।

ऐसा करने के लिए जाने का सबसे अच्छा तरीका क्या है?

संपादित करें: स्पष्ट करने के लिए, मैं खाका प्रसंग प्रोसेसर के बारे में और सिर्फ settings.py या कोई अन्य फ़ाइल में बातें डाल और सिर्फ आयात करने के बारे में पता है।

मेरा सवाल यह है कि, "अपने आप को दोहराएं" नियम का उल्लंघन किए बिना दो दृष्टिकोणों को कैसे जोड़ूं? अब तक के उत्तरों के आधार पर, मेरा दृष्टिकोण यहां है:

मैं global_constants.py नामक एक फ़ाइल बनाना चाहता हूं, जिसमें स्थिरांक की सूची होगी (MIN_TIME_TEST = 5 जैसी चीजें)। मैं import इस फ़ाइल को स्थिरांक प्राप्त करने के लिए किसी भी मॉड्यूल में कर सकता हूं।

लेकिन अब, मैं संदर्भ प्रोसेसर बनाना चाहता हूं जो इन सभी स्थिरांक को वापस कर देता है। जॉन मी के जवाब में, जैसे शब्दकोश में फिर से उन्हें सूचीबद्ध किए बिना, मैं इसे स्वचालित रूप से करने के बारे में कैसे जा सकता हूं?

उत्तर

14

लूपर और व्लादिमीर दोनों सही इमो हैं लेकिन आपको अपनी आवश्यकताओं को पूरा करने के लिए दोनों की आवश्यकता होगी।

  • हालांकि, स्थिरांक जरूरत नहीं है settings.py में हो, तो आप उन्हें कहीं भी रख सकते हैं और आपके विचार/मॉडल/मॉड्यूल कोड में उस जगह से उन्हें आयात कर सकते हैं। मैं कभी-कभी उन्हें __init__.py में डालता हूं यदि मुझे उनकी वैश्विक स्तर पर प्रासंगिक माना जाने की परवाह नहीं है।

  • इस तरह एक संदर्भ प्रोसेसर है कि चयनित चर टेम्पलेट गुंजाइश

    def settings(request): 
        """ 
        Put selected settings variables into the default template context 
        """ 
        from django.conf import settings 
        return { 
         'DOMAIN':  settings.DOMAIN, 
         'GOOGLEMAPS_API_KEY': settings.GOOGLEMAPS_API_KEY, 
        } 
    

में विश्व स्तर पर कर रहे हैं लेकिन यह overkill हो सकता है अगर आप django के लिए नए हैं यह सुनिश्चित करना होगा; शायद आप सिर्फ टेम्प्लेट स्कोप में चर डालने के लिए कह रहे हैं ...?

from django.conf import settings 

... 
# do stuff with settings.MIN_TIME_TEST as you wish 

render_to_response("the_template.html", { 
    "MIN_TIME_TEST": settings.MIN_TIME_TEST 
}, context_instance=RequestContext(request) 
+0

धन्यवाद, यह वास्तव में वह दिशा है जिसे मैं जाना चाहता हूं। लेकिन कृपया मेरी स्पष्टीकरण/अन्य प्रश्न देखें, यानी मैं सभी स्थिरांकों को दो बार सूचीबद्ध किए बिना आप क्या कह सकता हूं? –

+0

उन्हें सभी को एक शब्दकोश में लपेटें और फिर उस शब्दकोश को संदर्भ में रखें। आप उन्हें डॉट नोटेशन के माध्यम से एक्सेस करेंगे। उदाहरण: {{yourDict.yourConstant}} –

3

इसे अपने एप्लिकेशन की सेटिंग.py में डालने पर विचार करें। बेशक, इसे टेम्पलेट में उपयोग करने के लिए आपको टेम्पलेट को किसी अन्य सामान्य चर के रूप में उपलब्ध कराने की आवश्यकता होगी।

2

अपने स्थिरांक सभी टेम्पलेट्स में उपलब्ध कराने के लिए context processors का उपयोग करें (सेटिंग.py उन्हें व्लादिमीर के रूप में परिभाषित करने के लिए एक अच्छी जगह है)।

+0

उन्हें settings.py में परिभाषित करने के बाद संदर्भ प्रोसेसर में जोड़ने का एक अच्छा तरीका क्या है? मुझे सभी स्थिरांक के नामों को और बार दोहराना नहीं होगा। –

+0

सभी जानकारी लूपर राउच से जुड़े पृष्ठ पर उपलब्ध है। आपको एक पायथन फ़ंक्शन बनाना होगा जो वर्र्स का एक शब्दकोश लौटाएगा (जहां आप अपना स्थिरांक वापस कर सकते हैं) और अपने कार्य को TEMPLATE_CONTEXT_PROCESSORS सेटिंग में सूचीबद्ध करें। –

0

संदर्भ प्रोसेसर आप की तरह कुछ का उपयोग कर सकते हैं:

अपनी सेटिंग्स फ़ाइल में:

import settings 

context = {} 
for item in dir(settings): 
    #use some way to exclude __doc__, __name__, etc.. 
    if item[0:2] != '__': 
     context[item] = getattr(settings, item) 
4

अन्य लोगों के जवाब पर निर्माण करने के लिए, यहाँ एक आसान तरीका आप इस को लागू करेंगे:

GLOBAL_SETTINGS = { 
    'MIN_TIME_TEST': 'blah', 
    'RANDOM_GLOBAL_VAR': 'blah', 
} 

फिर, John Mee's context processor के बंद का निर्माण:

def settings(request): 
    """ 
    Put selected settings variables into the default template context 
    """ 
    from django.conf import settings 
    return settings.GLOBAL_SETTINGS 

यह डीआरवाई मुद्दे को हल करेगा।

या, आप कभी कभी ही वैश्विक सेटिंग्स का उपयोग करें और उन्हें दृश्य के भीतर से कॉल करना चाहते करने के लिए योजना बना रहे हैं: एक ही विचार जॉर्डन Reiter पर

def view_func(request): 
    from django.conf import settings 
    # function code here 
    ctx = {} #context variables here 
    ctx.update(settings.GLOBAL_SETTINGS) 
    # whatever output you want here 
0

जॉन मी के अंतिम हिस्से पर संस्करण, एक छोटे से विस्तार के साथ चर्चा करता है।

मान लीजिए आप क्या जॉर्डन सुझाव के सदृश अपनी सेटिंग्स में कुछ है - दूसरे शब्दों में, कुछ की तरह:

GLOBAL_SETTINGS = { 
    'SOME_CONST': 'thingy', 
    'SOME_OTHER_CONST': 'other_thingy', 
} 

आगे मान लीजिए आप पहले से ही चर से कुछ के साथ एक शब्दकोश है आप पारित करने के लिए करना चाहते हैं आपका टेम्पलेट, शायद आपके विचार के लिए तर्क के रूप में पारित किया गया है। आइए इसे my_dict पर कॉल करें। मान लीजिए कि आप my_dict में मान settings.GLOBAL_SETTINGS शब्दकोश में ओवरराइड करना चाहते हैं।

आप की तरह अपने ध्यान में रखते हुए कुछ करना हो सकता है:

def my_view(request, *args, **kwargs) 
    from django.conf import settings 
    my_dict = some_kind_of_arg_parsing(*args,**kwargs) 
    tmp = settings.GLOBAL_SETTINGS.copy() 
    tmp.update(my_dict) 
    my_dict = tmp 
    render_to_response('the_template.html', my_dict, context_instance=RequestContext(request)) 

यह आपको विश्व स्तर पर निर्धारित सेटिंग्स, अपने टेम्पलेट के लिए उपलब्ध होता है, और मैन्युअल रूप से उनमें से प्रत्येक के बाहर टाइप करने के लिए आप की आवश्यकता नहीं है।

यदि आपको नहीं टेम्पलेट, और न ही ओवरराइड करने के लिए किसी भी आवश्यकता पारित करने के लिए किसी भी अतिरिक्त चर है , तो आप सिर्फ कर सकते हैं:

render_to_response('the_template.html', settings.GLOBAL_SETTINGS, context_instance=RequestContext(request)) 

मैं यहाँ क्या कर रहा हूँ पर चर्चा & के बीच मुख्य अंतर क्या जॉर्डन है, वह है कि, settings.GLOBAL_SETTINGS किसी भी चीज को ओवरराइड करता है जो सामान्य डब्ल्यू/आपके संदर्भ शब्दकोश में हो सकता है, और मेरे साथ, मेरा संदर्भ शब्दकोश settings.GLOBAL_SETTINGS ओवरराइड करता है। YMMV।

1

संदर्भ प्रोसेसर अधिक गतिशील ऑब्जेक्ट डेटा को संभालने में बेहतर अनुकूल हैं - उन्हें documentation में मैपिंग के रूप में परिभाषित किया गया है और यहां कई पोस्टों में उन्हें संशोधित किया जा रहा है या विचारों के चारों ओर पारित किया गया है - यह नहीं है समझें कि एक टेम्पलेट वैश्विक जानकारी तक पहुंच खो सकता है, उदाहरण के लिए, आप दृश्य में एक विशेष संदर्भ प्रोसेसर का उपयोग करना भूल गए हैं। डेटा & परिभाषा द्वारा वैश्विक है जो टेम्पलेट को दृश्य जोड़ता है।

कस्टम टेम्पलेट टैग को परिभाषित करने का एक बेहतर तरीका है।इस तरह:

  • टेम्पलेट्स विचारों पर भरोसा नहीं कर रहे हैं वैश्विक सूचना उन्हें में पारित किया है करने के लिए
  • यह सूखी-एर है: वैश्विक सेटिंग्स को परिभाषित एप्लिकेशन कई परियोजनाओं को निर्यात किया जा सकता है, परियोजनाओं
  • भर में आम कोड को नष्ट
  • टेम्पलेट्स तय है कि क्या वे वैश्विक जानकारी के लिए उपयोग है, दृश्य कार्यों

उदाहरण में है नीचे मैं अपने समस्या से निपटने के - में और एक समस्या मैं आमतौर पर सामना करना पड़ता है, लोड हो रहा है - इस MIN_TIME_TEST चर में लोड हो रहा है यूआरएल जो मेरे पर्यावरण सी बदलते हैं hanges।

मैं 4 वातावरण है - 2 देव और 2 उत्पादन:

  • देव: django-वेब सर्वर, यूआरएल: स्थानीय होस्ट: 8000
  • देव: Apache वेब सर्वर: यूआरएल: sandbox.com ->
  • प्रॉड सैंडबॉक्स सर्वर 127.0.0.1 पर ले कर, यूआरएल: sandbox.domain.com
  • प्रॉड सर्वर: यूआरएल: domain.com

मैं अपने सभी परियोजनाओं 01,232 पर ऐसासभी यूआरएल को फ़ाइल में रखें, global_settings.py ताकि यह कोड से पहुंचा जा सके। मैं एक कस्टम टेम्पलेट टैग {% site_url%} परिभाषित करता हूं जो किसी भी टेम्पलेट में लोड किया जा सकता है (वैकल्पिक रूप से)

मैं global_settings नामक एक ऐप बनाता हूं, और सुनिश्चित करता हूं कि यह मेरी सेटिंग्स में शामिल है। INSTALLED_APPS tuple।

Django एक विधि प्रस्तुत करना() बताता है कि कैसे डेटा प्रदर्शित किया जाना चाहिए साथ नोड्स में टेम्प्लेटेड पाठ संकलित -। मैं एक उद्देश्य यह है कि नाम में पारित के आधार पर मेरे global_settings.py में मानों returnning द्वारा डेटा renders बनाया

यह इस तरह दिखता है: मेरे उदाहरण और अपने उदाहरण के लिए min_test_time के लिए SITE_URL:

from django import template 
import global_settings 

class GlobalSettingNode(template.Node): 
    def __init__(self, settingname): 
     self.settingname = settingname; 
    def render(self, context): 
     if hasattr(global_settings, self.settingname): 
      return getattr(global_settings, self.settingname) 
     else: 
      raise template.TemplateSyntaxError('%s tag does not exist' % self.settingname) 

अब, global_settings.py में मैं एक जोड़ी टैग रजिस्टर। इस तरह, जब किसी टेम्पलेट से {% min_time_test%} को बुलाया जाता है, तो यह get_min_time_test को कॉल करेगा जो मान = 5 में लोड करने का संकल्प करता है। मेरे उदाहरण में, {% site_url%} एक नाम-आधारित लुकअप करेगा ताकि मैं एक ही समय में परिभाषित सभी 4 यूआरएल रख सकूं और चुन सकूं कि मैं किस पर्यावरण का उपयोग कर रहा हूं। Django के सेटिंग्स में निर्मित बसों का उपयोग करने के बजाय यह मेरे लिए अधिक लचीला है। डेबग = सही/गलत ध्वज।

from django import template 
from templatenodes import GlobalSettingNode 
register = template.Library() 


MIN_TIME_TEST = 5 

DEV_DJANGO_SITE_URL = 'http://localhost:8000/' 
DEV_APACHE_SITE_URL = 'http://sandbox.com/' 
PROD_SANDBOX_URL = 'http://sandbox.domain.com/' 
PROD_URL = 'http://domain.com/' 

CURRENT_ENVIRONMENT = 'DEV_DJANGO_SITE_URL' 



def get_site_url(parser, token): 
    return GlobalSettingNode(CURRENT_ENVIRONMENT) 

def get_min_time_test(parser, token): 
    return GlobalSettingNode('MIN_TIME_TEST') 

register.tag('site_url', get_site_url) 
register.tag('min_time_test', get_min_time_test) 

ध्यान दें कि यह काम करने के लिए, Django global_settings.py उम्मीद कर रही है एक अजगर अपने Django एप्लिकेशन के तहत templatetags बुलाया पैक पर मौजूद होने की। यहाँ मेरे Django एप्लिकेशन global_settings कहा जाता है, तो मेरे निर्देशिका संरचना की तरह दिखता है:

/project-name/global_settings/templatetags/global_settings.py आदि

अंत टेम्पलेट चुनता वैश्विक सेटिंग्स में है या नहीं लोड करने के लिए है कि क्या , जो प्रदर्शन के लिए फायदेमंद है। Global_settings में पंजीकृत सभी टैग का पर्दाफाश करने के लिए इस पंक्ति को अपने टेम्पलेट में जोड़ें।py:

{% load global_settings %} 

अब, अन्य परियोजनाओं MIN_TIME_TEST या इन परिवेशों उजागर बस आपको यह एप्लिकेशन इंस्टॉल कर सकते हैं की जरूरत है कि =)