I have a Django model which stores inputs from a form, now that I have the data stored in Django I need to import those models to a python file.
As per documentation,
If you’re using components of Django “standalone” – for example,
writing a Python script which loads some Django templates and renders
them, or uses the ORM to fetch some data – there’s one more step
you’ll need in addition to configuring settings.
After you’ve either set DJANGO_SETTINGS_MODULE or called configure(),
you’ll need to call django.setup() to load your settings and populate
Django’s application registry. For example:
import django
from django.conf import settings
from myapp import myapp_defaults
settings.configure(default_settings=myapp_defaults, DEBUG=True)
django.setup()
# Now this script or any imported module can use any part of Django it needs.
from myapp import models
Related
Can I receive access to Model from some custom file. For example I create folder in my project with name Bot. Create some custom_file.py, in current file call model from other app.
For example:
from trading.models import Values
Then I get an error:
django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
Also try solution like this in my custom_file.py:
import os
import django
os.environ["DJANGO_SETTINGS_MODULE"] = 'trading.settings'
django.setup()
But still doesn't work.
You don't need to do any fancy stuff from within the file, just create it in your app module (folder) and import any model you want, exactly as in the example you provided.
I like the Django ORM. It's simple, easy to use, and reasonably powerful.
I'm currently developing some internal sites for the VFX company I work for, for which I've used Django. In the meantime, we are developing other python applications and libraries to be used in various contexts in production. There's a number of places in which our core library needs to be interacting with some databases, and using an ORM like Django would really help things. I'm aware of other options like SqlAlchemy or PeeWee, but I'd like to see if Django will work since I use it on the websites and I like its API better.
Using Django as an ORM in a library is tricky (as I explored in a previous question), because Django expects to be used as a website with "apps". In a library, I might want to define any number of data models, which would exist in appropriate places in the library but not inside any Django app (as we're not using any other parts of the framework). So far so good.
I can create a baseclass for my models anywhere in the library as follows:
from django.db import models
from django.apps import apps
import django.conf
django.conf_settings.configure(
DATABASES = ...
)
apps.populate((__name__,))
class LibModel(models.Model):
class Meta:
abstract = True
app_label = __name__
Then anywhere in the library I can create my own models with this baseclass. Since I'm not relying on the "app" for the database names, I need to state them explicitly.
class SpecificModel(LibModel):
# fields go here
class Meta(LibModel.Meta):
db_table = "specific_model_table_name"
This gets around my concern of having to simulate the structure of an "app". The name property in the base class supplies Django with all it needs, and then Django quits whining about not finding an app. The other model files can live wherever they want.
However, there is a glaring use case where this all falls apart. Say that my Django web application wants to use some functionality from the company core python library, which now uses the Django ORM for various things. Since I make a call to django.conf.settings.configure in the library, Django is going to scream about defining the settings more than once when it tries to run the main application.
So basically, a library using the Django ORM is incompatible with Django. Wonderful.
Is there any way around this? I mean, it's a lovely ORM - is it really this impossible to use in a standalone modular way? Is the Django architecture utterly singleton in nature, making this impossible?
*Not a duplicate
I'm trying to have a company python library that uses Django as an ORM. Some of the things that could depend on it might be Django websites themselves. How do I get around Django's singleton insistence on only setting the settings config once? Or is it possible? None of these answers address this!
You can check if django has already been configured.
from django.apps import apps
from django.conf import settings
if not apps.ready:
settings.configure()
django.setup()
When starting Django application - core python library can be configured as separate app an be loaded on startup.
Also, check this answer on dynamic app loading at runtime.
A simple answer is how to initialize Django in a standalone application and do it compatible with Django applications.
import os
import django
if not 'DJANGO_SETTINGS_MODULE' in os.environ:
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysettings'
# # or without DJANGO_SETTINGS_MODULE directly
# from django.conf import settings
# settings.configure(DATABASES=... other...)
django.setup()
# this shouldn't be before DJANGO_SETTINGS_MODULE or settings.configure(...)
from myapp.models import MyModel
# this shouldn't be called before django.setup()
queryset = MyModel.objects.filter(...)
This is more compatible with Django then the answer by Oleg Russkin (where a risk of cyclic dependency at django.setup() is possible if the code is called inside inside a setup() initiated by another similar code or a normal Django project started by manage. It is similar to manage.py where django.setup() is also called internally by execute_from_command_line(sys.argv). The setup initializes all modules related to INSTALLED_APPS all urls modules and consequently all views etc. Many of them are lazy, but still. If any code called by setup() depends on this then neither the condition not apps.ready doesn't help. The setup() is not reentrant and the startup fails.)
Much more general answer
An important concept of Django is to support writing reusable parts of code ("applications" in Django terminology, that can be developed and tested independently. There can be also a tree of dependencies, but uncontrolled mutual dependencies should be avoided if possible) Reusable applications are expected that they can be easier combined to whole project ("project" in Django terminology is with all settings necessary to run it by Python.)
The only unavoidable and useful "singleton" in Django ORM are database connections django.db.connections and django.conf.settings especially INSTALLED_APPS. Only one connection should be used to the same database from the same process or thread.
Django is very configurable. An extreme example: It is possible to write a single file project where all code like settings, models, URL configs and views is defined in one file. That extreme that is probably useful only for some special tests or very short demos or as an exercise. It is even possible to define a project by one file with two "reusable" applications :-)
Django supports also "legacy databases" where the database structure is shared with existing non Django applications and models can be created by inspectdb command. Table names in such models are explicit and don't contain the app name. On the other hand the app name prefix is useful to prevent a possible conflict of the same table names from independent "applications". An important decision is if you can use it as a "legacy" database or a normal Django database.
You can decide between following two solutions or to combine them:
Use e.g. foo_models or bar.models and import all models from them e.g. to app.models and add only that "app" to INSTALLED_APPLICATIONS. This can be viable if it is only for one company and never otherwise and central name assigment is possible. (easiest but little naive)
Use some coarse separation of namespaces to several apps. You should probably use not more than one app with simple names without app name prefix.
Think ahead about migrations**. They will be probably very complicated and very soon impossible if you will create later more projects for the same database and different subsets of database tables without separating them to more apps and without app namespace.
There is really no "singleton" in Django ORM except of django.db.connections itself. If you use more databases you can direct some tables to a specific database by DATABASE_ROUTERS, even with two different models that use the same table name without a prefix.
My site is named ficosa. I have a Django server set up with a sqlite database that contains a table named core_Data. Now, I am developing a python file named serverMQTT.py that should insert data into that sqlite database. This file is outside Django so in order to import the Django models from ficosa site I call django.setup()
import django
from django.conf import settings
from ficosa import settings as fsettings
settings.configure(default_settings=fsettings, DEBUG=True)
django.setup()
Now this script or any imported module can use any part of Django it needs.
from core.models import Data
However, I am having an error:
AttributeError: 'module' object has no attribute 'LOGGING_CONFIG'
I would be gratefull if sombody could help me
That's not how you configure settings in a standalone app. Note what the documentation says:
Be aware that if you do pass in a new default module, it entirely replaces the Django defaults, so you must specify a value for every possible setting that might be used in that code you are importing.
Presumably, your fsettings module only contains database settings. In which case, just override that one thing:
settings.configure(DATABASES=fsettings.DATABASES, DEBUG=True)
I have JSON data coming through various external API's into my Django project. I have two apps, one called 'products' and other 'extract'. Through product app, have created the database and rendered the views required. Objective of extract app is to parse the JSON data and create/update the fields in the Django database. I have this code saved in extract/views.py as shown below -
import json
import urllib2
from products.models import Product
url = " .........."
.............
for i in data[results]:
Product.objects.get_or_create (...........)
The issue I am having is this code is working well in python shell. It is extracting all the JSON data and updating the database. But, when I run the script on the command line outside of Python shell, it is giving error - 'Import error: No module named products.models'.
Django requires you to run python manage.py shell in order for the product app's models and Django internals to be initialized.
Check out this blog post by Stavros Korokithakis to convert your code into a standalone script.
I believe the error is with the directory set up. Make sure all your migrations are done as well as the initial folder has the paths to your apps. Possible you need to include the paths to each app in the other's settings.
I'm making a very very reusable CMS in Django. I'm trying not to hardcode anything, so I want a config.py or something for the app itself.
I want to use it in templates (something like {{ config.SITE_NAME }}) and just regular Python code (views, models), etc.
How would I go about doing that?
Django already has the settings.py file and an interface to use the values from there, is that not good enough? Accessing settings in your code is easy:
from django.conf import settings
do_something_with(settings.MY_CONFIG_VARIABLE)
In your template it requires a bit more work, like making a context processor for example. This answer shows you have to make a context processor that exposes values from settings to your template.
settings.py serves this purpose already in django. You can add custom settings to it for your application.
https://docs.djangoproject.com/en/dev/topics/settings/#using-settings-in-python-code
When you create a django project, it automatically creates a settings.py file. Put your settings in that file, and then :-
from django.conf import settings
settings.YOUR_SETTING
also, if you have some settings, that will vary depending upon the machines (eg. production/test servers).
Then just add eg. conf/local_settings.py file and put the machine specific settings in that file, and in settings.py just do :-
from conf.local_settings import *
at the end of settings.py
Make sure you ignore local_settings.py from your VCS check-in (eg. in case of git add local_settings.py to .gitignore