django: changing settings while running - django

Is there a problem to change one of the settings when django is running?
For example, I'd like to change REGISTRATION_OPEN from the django-registration app from False to True when it is live.
I do not want to stop the server to change this value.
Is there a cache that would prevent the new value to be used?
Should I rather consider a table to store settings that can be changed when it is live?
Thanks

Django Livesettings is an excellent option: http://django-livesettings.readthedocs.org/en/latest/about.html

Related

Setting a project level django constant

In my application, I set one configuration in my database (lets say buffer_radius) that is not going to change very frequently. I want to set one constant BUFFER_RADIUS in Django so that every-time Django restarted/redeployed, the value of this constant set to buffer_radius. I want to do this to minimize database call.
Put it the settings.py and you can use Django-constance if you want your admins to change the value from Django Admin.

How to update db setting in django at runtime?

To be more specific, I want to retrieve db setting from a config server when django project starts, and use it to setup django db connection
Someday in the future, the setting in the config server may be changed (for example, change the user password) and pushed to django project then reset the db connection, so I can use new setting without restarting django project or updating project code
Is there a way to do that?
Or what's the right way to hide the db sensitive information (password, etc) from django project code?
Any helps will be grateful, thanks~

set a global setting during django startup

The figure shows my django structure. I don't have a django app according to django glossary.
When django starts, I want to load a system configuration (I know how to run a Linux command) and save the result to a place where view.py can access. How would I implement it?
I tried the following options:
First, I looked at Django settings, but it discourages altering values in settings.py at runtime. Second, from what I understand, Django Applications is saying I need to have a django app in order to use AppConfig.ready() which sets something global settings. Unless my folder structure is horribly wrong, I don't want to change it or switch to a django app.
I'm using django 3.1 on Linux.
You could alter django settings at runtime like this however it is discouraged.
from django.conf import settings
settings.CUSTOM_KEY = True

How to implement settings in admin?

I have Django project with my own app. This app has only two models. I need configure some options specific for this app, but in default Django admin panel.
I was thinking to create a model for example: SettingsApp and create one entry with my settings, but in admin panel, user can be add other entries or delete existing entry and app will not work. How to do it?
You should take a look at:
https://github.com/jqb/django-settings
and check if it fits well for you.
This work for my settings model:
class SettingsAdmin(admin.ModelAdmin):
def has_add_permission(self, request):
return False
def has_remove_permission(self, request):
return False
I recommend you to take a look at application django-livesettings from here. As said in documentation:
Django-Livesettings is a project split from the Satchmo Project. It
provides the ability to configure settings via an admin interface,
rather than by editing settings.py. In addition, livesettings allows
you to set sane defaults so that your site can be perfectly functional
without any changes. Livesettings uses caching to make sure this has
minimal impact on your site’s performance.
Finally, if you wish to lock down your site and disable the settings,
you can export your livesettings and store them in your settings.py.
This allows you have flexibility in deciding how various users
interact with your app.
Livesettings supports several types of input choices:
Boolean
Decimal
Duration
Float
Integer
Positive Integer
String
Long string
Multiple strings
Long multiple strings
Module values
Password
Livesettings has been used for many years in the satchmo project and
is considered stable and production ready.

How to alter django settings based on current request?

I'm running multiple sites from a single django instance, and expect the framework to eventually serve several hundred sites from one or several installations.
I need to patch some django settings based on the current request. I've written some middleware to monkey patch the settings, but I need these settings to be patched before the middleware gets invoked because other apps aren't taking the monkey-patched changes (i.e. apps get run then middleware gets run so the apps don't use the monkey-patched settings).
I should also add this is mainly for the benefit of third-party apps that I haven't written, so I don't want to go round adding decorators or anything like that because that would mess up my upgrade path.
So:
How can I get access to the current request in an app's init.py file?
Will an app's init.py get called once per request or only once? If it's only once, how else could I do this so I can manipulate the settings once per request?
Is it safe to do this kind of monkey patching? I know it makes code a bit more opaque, but I don't want to use different wsgi files per site because I want to allow users to edit some of these settings and have my monkey patching come from the database.
Is there a better solution that would allow certain settings to be stored in the database?
This module - django-tupperware does what you are asking about: https://bitbucket.org/jiaaro/django-tupperware/
Give it a try.
Never ever ever change settings on the fly. You cannot predict how the application may one day be deployed, and in most of them the project will fail in.. interesting ways.
If you really want to have hundreds of sites which will be dynamically reconfigured all the time, you might try to Djangos django/conf/__init__.py which is used to supply the settings to the rest of the framework. You might be able to alter it in a way it depends on the request and it's Host field. Or you'll get many interesting failures at the very least.
My solution to this problem is to give each request, ALL the settings and update them on the fly with a middleware, how do i do this?
Is rather simple:
This is the middleware that does it all
from django.conf import settings
class DumpObject: pass
class Settings(object):
def process_request(self,request):
request.settings = DumpObject()
for setting in dir(settings):
if not setting.startswith('__'):
setattr(request.settings, setting, getattr(settings,setting))
The DumpObject is just there so i can use the object.property notation, it could have been a dictionary, but i wanted to keep some similarity in the syntax.
This assumes that none of your settings name starts with __ which is a fair assumption.
So if i want to override a particular setting, i don't keep a settings file i do it in this middleware. like this:
class Settings(object):
def process_request(self,request):
request.settings = DumpObject()
for setting in dir(settings):
if not setting.startswith('__'):
setattr(request.settings, setting, getattr(settings,setting))
if 'mydomain' in str(request.host): #this is thanks to django-hosts project
request.settings.GOOGLE_ANALYTICS_ID = '89298393-238'
Of course this doesnt take into account the problem of accessing the settings the old way
from django.conf import settings
settings.GOOGLE_ANALYTICS_ID = 'the value in settings.py'
But it really doesn't matter because you will probably only want to change the settings on the context of having a request object, available.