2011-04-08 19 views
21

के लिए डिफ़ॉल्ट मान को परिभाषित करने के लिए कैसे करें Django प्रलेखन mentions कि आप django.conf.settings पर अपनी सेटिंग्स जोड़ सकते हैं। अगर मेरी परियोजना की settings.py को परिभाषित करता हैकस्टम Django सेटिंग

APPLES = 1 

मुझे लगता है कि इस परियोजना में मेरी क्षुधा में settings.APPLES साथ कि उपयोग कर सकते हैं तो।

लेकिन अगर मेरा settings.py उस मान को परिभाषित नहीं करता है, तो settings.APPLES तक पहुंच स्पष्ट रूप से काम नहीं करेगा। APPLES के लिए डिफ़ॉल्ट मान को परिभाषित करने का कोई तरीका है जिसका उपयोग settings.py में कोई स्पष्ट सेटिंग नहीं है?

मैं मॉड्यूल/पैकेज में डिफ़ॉल्ट मान को परिभाषित करना चाहता हूं जिसके लिए सेटिंग की आवश्यकता है।

उत्तर

24

मेरे ऐप्स में, मेरे पास एक अलग सेटिंग्स.py फ़ाइल है। उस फ़ाइल में मेरे पास एक get() फ़ंक्शन है जो प्रोजेक्ट सेटिंग्स.py फ़ाइल में दिखता है और यदि नहीं मिला तो डिफ़ॉल्ट मान देता है।

from django.conf import settings 

def get(key, default): 
    return getattr(settings, key, default) 


APPLES = get('APPLES', 1) 

तब मैं कहाँ सेब का उपयोग करने की जरूरत है मेरे पास है:

from myapp import settings as myapp_settings 

myapp_settings.APPLES 

यह अगर विशेषता पाया या है की अनुमति देता है परियोजनाओं में एक ओवरराइड settings.py, getattr वहाँ पहले की जाँच करें और मान प्रदान करेंगे अपनी ऐप सेटिंग्स फ़ाइल में परिभाषित डिफ़ॉल्ट का उपयोग करें।

+0

क्या यह नाजुक नहीं है? 'App_settings.py' से पहले प्रोजेक्ट' सेटिंग्स.py' आयात किए जा रहे हैं? – Flimm

1

माइक के उत्तर से शुरू होने पर, अब मैंने डिफ़ॉल्ट सेटिंग इंटरफ़ेस के साथ एक कक्षा में डिफ़ॉल्ट सेटिंग हैंडलिंग लपेट ली है।

हेल्पर मॉड्यूल:

from django.conf import settings 

class SettingsView(object): 
    class Defaults(object): 
     pass 

    def __init__(self): 
     self.defaults = SettingsView.Defaults() 

    def __getattr__(self, name): 
     return getattr(settings, name, getattr(self.defaults, name)) 

उपयोग:

from localconf import SettingsView 

settings = SettingsView() 
settings.defaults.APPLES = 1 

print settings.APPLES 

यह django.conf.settings से मूल्य, या डिफ़ॉल्ट अगर यह वहाँ सेट नहीं है प्रिंट करता है। यह settings ऑब्जेक्ट का उपयोग सभी मानक सेटिंग मानों तक पहुंचने के लिए भी किया जा सकता है।

+0

मुझे लगता है कि आसान सेटिंग्स के लिए, ऐप विशिष्ट सेटिंग्स को मुख्य सेटिंग्स से स्पष्ट रूप से नामित और अलग किया जाना चाहिए। –

1

आप यह देखने के लिए जांच सकते हैं कि सेटिंग परिभाषित की गई है, और यदि नहीं, तो इसे डिफ़ॉल्ट मान दें। इस तरह

from django.conf import settings 

def setting_default(name, default_value): 
    value = getattr(settings, name, default_value) 
    setattr(settings, name, value) 

और फिर एप्लिकेशन कि सेटिंग (शायद models.py में) की आवश्यकता है में इसका इस्तेमाल करते हैं: उदाहरण के लिए आप इस तरह एक सहायक समारोह setting_default परिभाषित कर सकते हैं

setting_default('APPLES', 1) 

इस तरह जो कोई भी उपयोग कर रहा है अपने ऐप को कुछ खास करने की ज़रूरत नहीं है।

10

कैसे बस के बारे में:

getattr(app_settings, 'SOME_SETTING', 'default value') 
+0

यह कुछ अन्य सुझावों की तुलना में बहुत आसान है, लेकिन यदि आप डीआरवाई अवधारणा को तोड़ने के बाद एक सेटिंग/चर का उपयोग करने का इरादा रखते हैं, तो इस मामले में अन्य समाधान काम कर सकते हैं। विचार के लिए भोजन :) – daniel

+0

यह DRY कैसे तोड़ता है? – Charlie

+0

यदि आप अपने आवेदन में एक से अधिक बार SOME_SETTING का उपयोग करना चाहते हैं तो आपको यह 'getattr (app_settings,' SOME_SETTING ', default_value) रखना होगा, हर जगह आप इसे – daniel

5

यहाँ दो समाधान कर रहे हैं। दोनों के लिए आप अपने अनुप्रयोगों में settings.py फ़ाइलों को सेट कर सकते हैं और उन्हें डिफ़ॉल्ट मानों से भर सकते हैं। एक भी आवेदन

उपयोग from MYAPP import settings बजाय from django.conf import settings अपने कोड में लिए

कॉन्फ़िगर डिफ़ॉल्ट मान।

संपादित YOURAPP/__init__.py:

from django.conf import settings as user_settings 
from . import settings as default_settings 

class AppSettings: 
    def __getattr__(self, name): 
     # If the setting you want is filled by the user, let's use it. 
     if hasattr(user_settings, name): 
      return getattr(user_settings, name) 

     # If the setting you want has a default value, let's use it. 
     if hasattr(default_settings, name): 
      return getattr(default_settings, name) 

     raise AttributeError("'Settings' object has no attribute '%s'" % name) 

settings = AppSettings() 

एक पूरी परियोजना

उपयोग from MYPROJECT import settings बजाय from django.conf import settings अपने कोड में के लिए कॉन्फ़िगर डिफ़ॉल्ट मान।

संपादित MYPROJECT/MYPROJECT/__init__.py

import os, sys, importlib 
from . import settings as user_settings 

def get_local_apps(): 
    """Returns the locally installed apps names""" 
    apps = [] 
    for app in user_settings.INSTALLED_APPS: 
     path = os.path.join(user_settings.BASE_DIR, app) 
     if os.path.exists(path) and app != __name__: 
      apps.append(sys.modules[app]) 
    return apps 

class AppSettings: 
    SETTINGS_MODULE = 'settings' 

    def __getattr__(self, setting_name): 

     # If the setting you want is filled by the user, let's use it. 
     if hasattr(user_settings, setting_name): 
      return getattr(user_settings, setting_name) 

     # Let's check every local app loaded by django. 
     for app in get_local_apps(): 
      module_source = os.path.join(app.__path__[0], "%s.py" % self.SETTINGS_MODULE) 
      module_binary = os.path.join(app.__path__[0], "%s.pyc" % self.SETTINGS_MODULE) 
      if os.path.exists(module_source) or os.path.exists(module_binary): 
       module = importlib.import_module("%s.%s" % (app.__name__, self.SETTINGS_MODULE)) 

       # Let's take the first default value for this setting we can find in any app 
       if hasattr(module, setting_name): 
        return getattr(module, setting_name) 

     raise AttributeError("'Settings' object has no attribute '%s'" % setting_name) 

settings = AppSettings() 

यह समाधान स्थापित करने के लिए और अधिक आसान लग सकता है, लेकिन यह गारंटी नहीं है कि अच्छा डिफ़ॉल्ट मान लौटा दी जाएगी। यदि कई एप्लिकेशन एक ही वैरिएबल को उनके settings.py में घोषित करते हैं, तो आप यह सुनिश्चित नहीं कर सकते कि कौन सा डिफ़ॉल्ट मान आपके द्वारा पूछा जाएगा।

0

मुझे हाल ही में एक ही समस्या थी और एक Django ऐप बनाया गया जो कि इस तरह के मामले के लिए उपयोग करने के लिए डिज़ाइन किया गया है। यह आपको कुछ सेटिंग्स के लिए डिफ़ॉल्ट मान परिभाषित करने की अनुमति देता है। यह पहले जांच करता है कि सेटिंग वैश्विक सेटिंग्स फ़ाइल में सेट है या नहीं। यदि नहीं, तो यह डिफ़ॉल्ट मान वापस कर देगा।

मैं इसे बढ़ाया गया है भी कुछ प्रकार जाँच या डिफ़ॉल्ट मान के पूर्व से निपटने के लिए अनुमति देने के लिए

एप्लिकेशन में पाया जा सकता है (जैसे एक बिंदीदार वर्ग पथ वर्ग में ही लोड पर बदला जा सकता है): https://pypi.python.org/pypi?name=django-pluggableappsettings&version=0.2.0&:action=display

संबंधित मुद्दे