set a global setting during django startup - django

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

Related

Django - 'myapp' vs 'myapp.apps.myappConfig' in settings.py Installed Apps

I know this might sound stupid but I was just wondering what's the difference if I just type 'myapp' instead of 'myapp.apps.myappConfig' in my Installed Apps list. Is it something related to models or what?
Regards
If you use myapp.apps.myappConfig, then you are explicitly telling Django to use that app config class.
Changing the app config class lets you change the behaviour of the application, for example, when you use the admin app, you can use django.contrib.admin.apps.AdminConfig which autodiscovers apps, or django.contrib.admin.apps.SimpleAdminConfig, which does not.
If you just use myapp, then Django will try to use default_app_config. If that isn't set, then it will use the default AppConfig.
A lot of the time, there isn't any customisation in myappConfig, or default_app_config is set, so you'll get the same behaviour whichever style you use in INSTALLED_APPS.
Ever since AppConfig was added in Django 1.7, the recommendation has been to use ``myapp.apps.myappConfigbecause it's explicit, and avoid usingdefault_app_config`.
However, in practice, it seems that users have preferred the simplicity of using myapp. Therefore, there's an open pull request which will remove default_app_config, and automatically select the app config class when there is only one.

Using Scrapy DjangoItem with Django best way

I am am new to Django / Scrapy and well to programming in general. I am trying to make a Django site to help me learn.
What I want to do is Scrape product information from different sites and store them in my postgres database using DjangoItem from Scrapy.
I have read all the docs from both Scrapy and Django. I have searched here and other sites for a couple days and just couldn't find exactly what I was looking for that made the light bulb go off.
Anyway, my question is, what is the standard for deploying Scrapy and Django together. Ideally I would like to scrape 5-10 different sites and store their information in my database.
Scrapy's docs are a little short on information on the best way to implement DjangoItem.
1) Should the Scrapy project be inside my Django app, at the root level of my Django project or outside all together.
2) Other than setting DjangoItem to my Django model, do I need to change any other settings?
Thanks
Brian
I generally put my scrapy project somewhere inside my Django project root folder. Just remember you will need to make sure both projects are in the python path. This is easy to do if you are using virtualenv properly.
Aside from that as long as you can import your Django models from Scrapy i think everything else in the Scrapy docs is very clear. When you import your Django model, the Django settings are set up at that point, this means your database connection etc should all be working fine as long as they are already working in Django.
The only real trick is getting the python path set up properly (which is probably a topic for another questions).

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.

Django on Twisted with multiple virtual hosts?

I have a django website that I am hosting on twisted via the django WSGIHandler as described here - http://www.clemesha.org/blog/Django-on-Twisted-using-latest-twisted-web-wsgi
All seems OK up to the point where I want to add an extra "site" configuration to my django site using the django Sites framework. Doing so, I add an extra settings.py file for the new site and that seems to work.
What I then want to do is use the twisted NameVirtualHost class to be able to direct one domain (say site1.example.com) to the first settings file, then use another domain (say site2.example.com) to use the second settings file. This works with Apache & mod_wsgi.
The problem I face is that the twisted code can only access one django environment at a time. If I call setup_environ with the first settings file and setup a host for the first domain, a subsequent call to setup_environ will replace the settings file in use so therefore only one set of settings can be used at one time.
Any ideas how to proceed?
Gave up on this in the end. Looks like you cannot easily access 2 Django environments within the same twisted instance. I think it would require multiple instances of twisted with a reverse proxy or some sort of multiprocess hacking - either way its not worth the effort for me so I'm going to try something else...

How to use admin interface if I have no application?

I am creating a Django based app and I'd like to put everything under the root in the following structure:
/path/to/my/app/
settings.py
models.py
urls.py
admin.py
...
One problem that I run into is the admin interface doesn't include whatever models I have that are registerd in admin.py usin
admin.site.register(models.MyModel)
Usually that's done by using auto discover in urls.py, but now I have no registered "app", the auto discover doesn't work anymore. Is there anyway I can still use the admin interface?
Thanks.
Django simply doesn't work without apps. They're the fundamental building block of a Django site. A whole range of things, not just the admin, will fail to work. Why do you want to do this?
Putting the app in the django-style directory structure will make your project easily extensible if you decide to add functionality later.