Access python script from one project to another - django

Main folder
|-project1
|-project2
I have the above structure for django projects.
When I am in project1 in a script i used os.chdir(to_project2) to project 2
I want to access project2's settings.py and fetch some attributes. Is it possible?

#You need to point your directory.[Ex: project2]
import os
os.chdir(project2 )
cd = os.getcwd()
# print the current directory
print("Current directory:", cwd)
#For Access the Django setting attributes
import django
from django.conf import settings
All of those aforementioned code you may use from one of your python file: something.py

Related

Django executing tests for app not in INSTALLED_APPS

Under my Django project there are a few apps and all of them have unit tests. One of them that I'm working right now is supposed to be included only in dev/stage environments, so I'm enabling it using a environment variable.
When this variable is present it is added to INSTALLED_APPS and it is working just fine, the problem is that Django is executing the tests for this app even when it is not in INSTALLED_APPS, and it fails with the following message:
ImportError: Failed to import test module: debug.tests.unit.test_services`
...(traceback information)...
RuntimeError: Model class debug.models.Email doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
When I define the app_label in the class Meta of models in this app the error is different, it says it can't find a table, I assume that this is because the app is not in INSTALLED_APPS, so it's migrations are not executed.
OperationalError: no such table: debug_email
I'm not sure why Django executes the tests for all apps, but not it's migrations.
Am I missing something from Django configuration for tests?
https://docs.python.org/3/library/unittest.html#unittest.TestLoader.discover says:
If load_tests exists then discovery does not recurse into the package, load_tests is responsible for loading all tests in the package.
So in the lowest __init__.py in your app which you don't always want run:
from django.apps import apps
def load_tests(loader, tests, pattern):
from django.conf import settings
if apps.is_installed("your_dev_app"):
# Actually load the tests - thanks to #barney-szabolcs
return loader.discover(start_dir=dirname(abspath(__file__)), pattern=pattern)
You need to return the discovered tests in load_tests.
So, adding to #DaveLawrence's answer, the complete code is:
# your_dev_app/__init__.py
from django.apps import apps
from os.path import dirname, abspath
def load_tests(loader, tests, pattern):
"""
loads tests for your_dev_app if it is installed.
"""
from django.conf import settings
if apps.is_installed("your_dev_app"):
return loader.discover(start_dir=dirname(abspath(__file__)), pattern=pattern)
When you run:
python manage.py test
the command will look per default recursive for all files with the pattern test*.py in the working directory. It isn't affected by INSTALLED_APPS in settings.py.
You can specify a certain app to test it:
python manage.py test app_label
or specify a path:
python manage.py test myapp/tests
If you want to exclude some tests you can tag them and use the option --exclude-tag.
Run python manage.py test --help to get information on all options.
The official documentation gives a lot of information on the different possibilities how to run the tests.
EDIT:
If you have apps that are required only in the development environment, but not in the production, you could split your settings.py. One possible solution would be to outsource all development settings into a file local_settings.py and exclude it from versioning or from the production branch, i.e. don't push it in the production environment.
local_settings.py
DEBUG = True
INSTALLED_APPS += (
# Django Debug Toolbar would be for example
# used only in development
'debug_toolbar',
'your dev app',
)
settings.py
try:
from .local_settings import *
except ImportError:
pass

Import error:No module named app1.models

In django, I am trying to populate my database from a csv file. with the help of this tutorial I wrote this code:
load_data.py:
# Full path and name to your csv file
csv_filepathname="Home/Desktop/MyProject/practice/app1/data/link1.csv"
# Full path to your django project directory
your_djangoproject_home="Home/Desktop/MyProject/practice/"
import sys,os
sys.path.append('Home/Desktop/MyProject/practice/')
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from app1.models import Link
import csv
dataReader = csv.reader(open(csv_filepathname), delimiter=',', quotechar='"')
for row in dataReader:
abc = Link()
abc.name = row[0]
abc.roll = row[1]
abc.save()
Now, when I run this, I get import error saying no module named app1.models. I can't figure it out. Can someone please highlight the mistakes?
my directory structure
I'm working on python 2.7 and django 1.6.
All package directories in Python need an __init__.py file, which can be empty.
You shouldn't really create app directories yourself anyway; you should have run manage.py startapp app1 which would have done it for you.
(Also, note you should absolutely not be using Django 1.6, which is several years old, unsupported, and almost definitely insecure. Upgrade to a more recent, supported, version.)

Dotted name in AppConfig

With django 1.7 they added support for configuration classes instead of the magic string from previous versions.
My project has several applications into a folder named apps which is added to the PYTHON_PATH.
After adding a simple AppConfig derived class I'm running into many import errors and I want to rule out silly mistakes.
Suppose this structure:
project_root/
my_project/
apps/
my_app/
another_app/
Would it be correct to have this config?:
# my_app/apps.py
class MyAppConfig(AppConfig):
name = 'apps.my_app'
# my_app/__init__.py
default_app_config='apps.my_app.apps.MyAppConfig'
# settings.py
INSTALLED_APPS = (
...
'apps.myapp.apps.MyAppConfig'
...
)
Curently the project fails when trying to import models (or tasks or any other module) issuing:
from apps.my_app.tasks import AwesomeTask
ImportError: no module named my_app.tasks
I solved a similar issue by renaming the apps folder. It was somehow conflicting with Django internals system.
I hope this helps someone.

Scrapy project can't find django.core.management

I'm trying to follow the method here to 'Scrapy' data from the web and simultaneously save that data directly to my Django database using Scrapy's item pipeline.
However, when I try to run scrapy crawl spidername, I'm getting the error:
ImportError: No module named django.core.management
At first I thought it was because my Scrapy project was outside of my Django project folder, but even after I moved the whole project into my Django project folder I kept getting the same error. If I open a python shell inside the Scrapy project folder in its new location (inside my Django project folder), import django.core.management works fine. So what's going on?
EDIT: Some additional info: I'm doing this on a Webfaction server, and the path to my Django project is /home/gchorn/webapps/django_app/django_project. I'm using Django version 1.4.1, Scrapy 0.16 and Python2.7. The layout of the Django+Scrapy project is as follows:
django_project/
__init__.py
manage.py
settings.py
urls.py
myproject #folder containing wsgi.py
app1
app2
app3
templates
ScrapyProject/
scrapy.cfg
ScrapyProject/
__init__.py
items.py
pipelines.py
settings.py
spiders/
__init__.py
my_spider.py
Try setting this in your Spider's settings.py:
import os
import sys
sys.path.append('/home/gchorn/webapps/django_app')
os.environ['DJANGO_SETTINGS_MODULE'] = 'django_project.settings'
Then you can import your model classes like:
from django_project.app1.models import some_model

Could not import/No module named Django Error with Apache

I had a small proof of concept set up on a development server on a local machine. I'm now trying to move it over to django on a production server, which I'm using webfaction for. However, now that I'm switched over to apache from the built in django server I get the following:
ViewDoesNotExist: Could not import orgDisplay.views. Error was: No module named orgDisplay.views
But when check my orgDisplay apps folder there is a view.py in it. What am I doing wrong? I've tried adding the following to my settings.py by suggestion of the django IRC room.
import sys
sys.path.append(r"/home/user/webapps/django_project/myproject/orgDisplay")
which is the path to my app.
any ideas on how to even begin to trouble shoot this?
Thanks in advance.
I assume you're using mod_wsgi (which is recommended by Django authors), not mod_python. This is the way you should use your sys.path:
django.wsgi:
import os, sys
sys.path.append(r"/home/user/webapps/django_project/myproject/")
os.environ["DJANGO_SETTINGS_MODULE"] = "settings"
sys.stdout = sys.stderr # Prevent crashes upon print
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
urls.py:
from django.conf.urls.defaults import *
urlpatterns = (
("", include("orgDisplay.urls")),
# ...
)
orgDisplay/urls.py:
import views
urlpatterns = (
(r'^some_view/$', views.some_view), # It is actually orgDisplay.views.some_view
# many more records ...
)
It is a bad idea to add project dir itself to path since you're be getting name conflicts between multiple projects.
I think you're appending the wrong directory to sys.path. I think Python is looking in the .../myproject/orgDisplay folder for the orgDisplay package. Try removing the orgDisplay from your string, like this:
import sys
sys.path.append(r"/home/user/webapps/django_project/myproject")
The other option would be to simply add myproject (or whatever your project is actually called) in the import statement.
# instead of "from orgDisplay import views"
from myproject.orgDisplay import views
Also, make sure to restart Apache after every edit.
looking at manage.py, it does it like so:
import sys
from os.path import abspath, dirname, join
from django.core.management import setup_environ
# setup the environment before we start accessing things in the settings.
setup_environ(settings_mod)
sys.path.insert(0, join(PINAX_ROOT, "apps"))
sys.path.insert(0, join(PROJECT_ROOT, "apps"))
Provided your WSGI file is in your project directory, a slightly more flexible way is this:
import os, sys
sys.path.append(os.path.dirname(__file__))
This will enable you to change your project location later without having to modify your WSGI file.