Vraag Hoe een standaardwaarde voor een aangepaste Django-instelling te definiëren


De Django-documentatie vermeldt waaraan u uw eigen instellingen kunt toevoegen django.conf.settings. Dus als mijn project is settings.py definieert

APPLES = 1

Ik heb daar toegang toe settings.APPLES in mijn apps in dat project.

Maar als mijn settings.py definieert die waarde niet, toegang settings.APPLES vanzelfsprekend zal het niet werken. Is er een manier om een ​​standaardwaarde te definiëren voor APPLES dat wordt gebruikt als er geen expliciete instelling is settings.py?

Ik zou graag de standaardwaarde definiëren in de module / het pakket waarvoor de instelling vereist is.


25
2018-04-08 22:56


oorsprong


antwoorden:


In mijn apps heb ik een afzonderlijk settings.py-bestand. In dat bestand heb ik een get () -functie die opzoekt in het bestand projects settings.py en als deze niet wordt gevonden, wordt de standaardwaarde geretourneerd.

from django.conf import settings

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


APPLES = get('APPLES', 1)

Daarna, waar ik toegang tot APP's moet hebben, heb ik:

from myapp import settings as myapp_settings

myapp_settings.APPLES

Dit maakt een overschrijving in de projecten settings.py mogelijk, getattr zal daar eerst controleren en de waarde retourneren als het attribuut wordt gevonden of de standaard gebruiken die is gedefinieerd in het instellingenbestand van uw apps.


26
2018-04-08 23:02



Wat dacht je van alleen:

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

12
2018-04-07 18:37



Hier zijn twee oplossingen. Voor beide kunt u instellen settings.py bestanden in uw toepassingen en vul ze met standaardwaarden.

Configureer de standaardwaarde voor een enkele applicatie

Gebruik from MYAPP import settings in plaats van from django.conf import settings in uw code.

Bewerk 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()

Configureer standaardwaarden voor een heel project

Gebruik from MYPROJECT import settings in plaats van from django.conf import settings in uw code.

Bewerk 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()

Deze oplossing lijkt eenvoudiger te installeren, maar garandeert niet dat de goede standaardwaarde wordt geretourneerd. Als verschillende toepassingen dezelfde variabele in hun settings.py declareren, weet u niet zeker welke de standaardwaarde zal teruggeven die u hebt gevraagd.


6
2017-08-25 22:00



Op basis van het antwoord van Mike heb ik nu de standaard instelling in een klasse gewikkeld met gebruiksvriendelijke interface.

Helper-module:

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))

Gebruik:

from localconf import SettingsView

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

print settings.APPLES

Hiermee wordt de waarde afgedrukt vanaf django.conf.settingsof de standaardinstelling als deze daar niet is ingesteld. Deze settings object kan ook worden gebruikt om toegang te krijgen tot alle standaard instellingswaarden.


2
2018-04-09 00:20



Ik had onlangs hetzelfde probleem en creëerde een Django-app die is ontworpen om te worden gebruikt voor precies zo'n geval. Hiermee kunt u standaardwaarden voor bepaalde instellingen definiëren. Vervolgens wordt eerst gecontroleerd of de instelling is ingesteld in het bestand met algemene instellingen. Als dit niet het geval is, wordt de standaardwaarde geretourneerd.

Ik heb het uitgebreid om ook wat typecontrole of pre-afhandeling van de standaardwaarde toe te staan ​​(een gestippeld klassenpad kan bijvoorbeeld bij belasting worden omgezet naar de klasse zelf)

De app is te vinden op: https://pypi.python.org/pypi?name=django-pluggableappsettings&version=0.2.0&:action=display


0
2017-09-29 14:45