django automate syncdb - django

I'm working on a project that includes a django server, and also a setup module.
The user will be configuring their system to run my program, which includes a django webserver element along with other items. I'm working on a setup module that assists the user in getting all of the settings correct and sets up all of the appropriate files. One of the things that I'd like to be during the setup process is essentially a "manage.py syncdb" command that creates an appropriate SQLite file and table from nothing.
I could grab the code found in manage.py and directly stick it into my setup module appropriately, but I'm not sure if there's a better approach that I'm missing - along the lines of two lines consisting of:
import django.something
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
django.something.syncdb()
Or something of the sort. Am I just missing something here?

This should do it:
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
from django.core import management
management.call_command('syncdb', interactive=False)
You can also do
import os
import settings
from django.core.management.commands import syncdb
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
syncdb.Command().execute(noinput=True)

Related

How to create a django package without setting DJANGO_SETTINGS_MODULE as environment variable?

I am creating a package that itself uses Django and I will be using it within other Django applications. The main issue I am facing is that I need to use to settings for various reasons such as logging and other extensive requirements. Since, this package does not have any views/urls, we are writing tests and using pytest to run them. The tests will not run without the settings configured. So initially I put the following snippet in the __init__ file in the root app.
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_package.settings")
django.setup()
Now, the test ran properly and the package as standalone app was working. But the moment I installed it in the main project, it overrides the enviroment variable with it's own settings and you can imagine the kind of havoc it would ensue.
This is the first time I am packaging a django app. So I am not well-versed with best practices and the docs are a little convoluted. I read the structure and code of various packages that use settings in their package but I am still not able to understand how to ensure the package accesses the intended settings and the project's settings is not affected at the same time.
While going throught the docs, I came accross this alternative to setting DJANGO_SETTINGS_MODULE, like this:
from django.conf import settings
settings.configure(DEBUG=True)
As shown here: https://docs.djangoproject.com/en/2.2/topics/settings/#using-settings-without-setting-django-settings-module
But where exactly am I supposed to add this? To every file where the settings are imported or will it work in the __init__ (Tried this but something isn't right, shows Apps aren't loaded )
I tried this as well where I imported my settings as defaults and called configure using them as defaults and called django.setup() as well but didn't do the trick:
# my_package/__init__.py
from django.conf import settings
from my_package import settings as default
if not settings.configured:
settings.configure(default_settings=default, DEBUG=True)
import django
django.setup()
Also, I need settings mainly because I have few parameters that can be overridden in the project that is using the package. When the package is installed, the overridden variables is what I should be able to access in the package during runtime.
If someone can guide on how to tackle this or have a better process of creating packages that need django settings, please do share.
So I ended up finding a way to work without setting the settings module as an environement variable. This enables me to use the specified settings by importing all the overridden settings as well as the default settings from:
Create a apps file for configuring your package as an app.
# my_package/apps.py
from django.apps import AppConfig
class MyPackageConfig(AppConfig):
name = 'my_package'
verbose_name = 'My package'
And, in your package's root. The following snippet in your __init__.py will only set the overridden settings:
# my_package/__init__.py
from django.conf import settings
import django
from my_package import settings as overridden_settings
from django.conf import settings
default_app_config = 'my_package.apps.MyPackageConfig'
if not settings.configured:
# Get the list of attributes the module has
attributes = dir(overridden_settings)
conf = {}
for attribute in attributes:
# If the attribute is upper-cased i.e. a settings variable, then copy it into conf
if attribute.isupper():
conf[attribute] = getattr(overridden_settings, attribute)
# Configure settings using the settings
settings.configure(**conf)
# This is needed since it is a standalone django package
django.setup()
Reference for what django.setup() will do:
https://docs.djangoproject.com/en/2.2/topics/settings/#calling-django-setup-is-required-for-standalone-django-usage
Points to keep in mind:
Since it is in the __init__, this will make sure if you import something from the package, the settings are configured.
As mentioned in the documentation above, you have to make sure that the settings is configured only once and similarly the setup method is called once or it will raise an Exception.
Let me know if this helps or you are able to come up with a better solution to this.

Error while deploying Django app on cpanel(shared hosting)

I m new to django. I created a web with dajngo,and successfully deployed it in the server
The python app has been successfully setup and virtual environment has been setup.
but while running the web it gives me "Server Error (500)" I don't know whats the problem.
I think error is in "wsgi.py" file but i'm unable to idenify it.
My wsgi file:
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'karan_web.settings')
application = get_wsgi_application()
my "passenger_wsgi.py" file is:
import imp
import os
import sys
sys.path.insert(0, os.path.dirname(__file__))
wsgi = imp.load_source('wsgi', 'karan_web/wsgi.py')
application = wsgi.application
can someone help me with it;
Sorry for the late answer, I had figured out the as to this just forgot to post it.
As I stated in my question, the actual problem was in passenger_wsgi.py, the django server starts with the wsgi.py and act as the gate way to the Django server.
So whenever a Django project is uploaded on the hosting server, It creates a passenger_wsgi.py file and one default wsgi.py, address of which is provided in passenger_wsgi.py by default.
So we just need to change that address and provide the address of our own wsgi.py in the project
In my case it was
import os
import sys
from karan_web import wsgi
application = wsgi.application
just edit in passenger_wsgi.py the following code.
from karan_web.wsgi import application
You need to check if your code syntax is correct and running properly. If its still doesn't work try to delete and recreate your database in cpanel and check if you have made all necessary migrations, don't forget to restart your python app. If after all these it still doesn't work check if all your files have the correct file permission(766).

Constantly need to reset django local settings module

I have made two settings files, one for local testing and one for production (heroku). Every time I pull and start working locally I need to run the following two commands for it to work:
export DJANGO_SETTINGS_MODULE=
DJANGO_SETTINGS_MODULE=projectName.settings_local
Without doing so I get the error that the local settings module cannot be found. This error appeared after I tried to have both settings files in a settings folder, which I did not get to work so I put them back in the original place. Does anyone have an idea how I can fix this?
In your wsgi.py file setdefault settings file path, in your case local setting file
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "projectName.settings_local")
application = get_wsgi_application()
You may also need to add in manage.py file
.....
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "projectName.settings_local")
.......
I hope this will help you.

How to get raven to report Django runscript exceptions to Sentry?

My Django web app logs exceptions to Sentry via raven. I also run a number of scripts (via manage.py runscript) as cron jobs. Right now any exceptions in those scripts are not being reported to Sentry. How do I set such reporting up?
As of version 5.3.1 of raven-python it should correctly patch Django's BaseCommand.execute, which effectively will handle errors in these commands (unless that parent call is never made).
For those out there that:
still have an issue of raven not patching itself for django management commands correctly
have Django==1.6.11
haven raven==5.12.0
I have found a fix that works for me.
The problem seems to be that raven is not patching BaseCommand.execute by the time it is called by Django. So to fix that, I make sure BaseCommand.execute is patched right away. I've updated my manage.py file to include the following lines:
from raven.contrib.django.management import patch_cli_runner
patch_cli_runner()
My final manage.py file looks like this:
#!/usr/bin/env python
from os.path import abspath
from os.path import dirname
import os
import sys
if __name__ == "__main__":
# add the ../ directory to the os path, so that we can find
# app.settings below
sys.path.insert(0, os.path.abspath(os.path.join(dirname(abspath(__file__)), '..')))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings")
from django.core.management import execute_from_command_line
from raven.contrib.django.management import patch_cli_runner
patch_cli_runner()
execute_from_command_line(sys.argv)

Cannot import django.core

I am trying to setup django with fastcgi on apache. Django is installed and seems to be running correctly but I am having problems with setting up fastcgi.
I decided to test out my dispatch.fcgi script in the interactive python shell line by line and the following line:
from django.core.servers.fastcgi import runfastcgi
results in the following error:
ImportError: No module named core.servers.fastcgi
I can import django with no problem but import django.core gives yet another ImportError (No module named core).
How can I go about ensuring that I can import django.core. If I can import django then in must be on my path, and so why can I not import core?
You probably have a file/folder called django somewhere in your path, that isn't the actual path.
try this
import sys
sys.path
And then check everything in that output to see if there is a file/folder called django(.py) somewhere.
If so, change the path (sys.path = ['/path/to/directory/below/django/install'] + sys.path) or move/rename the file.
Probably you have django.py module in your working directory or in any other that is in python path.
For anyone having this problem and coming across this question like I did, it turns out that fastcgi support has been removed as of Django 1.9, thus you will get this import error if trying to import it. Refer Using Django with virtualenv, get error ImportError: No module named 'django.core.servers.fastcgi'