Is there a way for me to configure PyCharm to run shell_plus instead of the default shell?
I've tried putting the text of the manage command in the 'Starting script' but then I get the folloiwing
django_manage_shell.run("/Users/cmason/counsyl/code/website/counsyl/product")
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
# The new Django 1.4 default manage.py wants "from django..." before
# importing settings, but we usually tinker with sys.path in
# settings_local.py, which is called from settings.py. Importing
# settings.py works but does mean some double importing. Luckily that
# module does very little work.
import settings
# appease pyflakes; don't ever do this in
# non-super-meta-namespace-trickery code
settings
from django.core.management import execute_from_command_line
execute_from_command_line("shellplus")
and it hasn't really run shell_plus.
It seems like the 'Starting script' happens in addition to rather than instead of the default.
Shell_plus automatically imports all Django model classes, among other things.
I got the model objects auto-loading by hooking into the shell_plus code. I appended this to the default startup script in Preferences > Build, Execution, Deployment > Console > Django Console:
from django_extensions.management import shells
from django.core.management.color import color_style
imported_items = shells.import_objects({}, color_style())
for k, v in imported_items.items():
globals()[k] = v
This was on PyCharm 2018.3.3 Pro
For completeness, this was the full content of starting script:
import sys; print('Python %s on %s' % (sys.version, sys.platform))
import django; print('Django %s' % django.get_version())
sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS])
if 'setup' in dir(django): django.setup()
import django_manage_shell; django_manage_shell.run(PROJECT_ROOT)
from django_extensions.management import shells
from django.core.management.color import color_style
imported_items = shells.import_objects({}, color_style())
for k, v in imported_items.items():
globals()[k] = v
I've been looking for a solution to the same problem, and I ended up here. I tried solutions proposed by others, but none of those appeared to solve this issue. So I decided to find another solution. This is what I came up with:
The code block below is the original Django Console starting script of PyCharm 2019.2:
import sys, django
print('Python %s on %s' % (sys.version, sys.platform))
print('Django %s' % django.get_version())
sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS])
if 'setup' in dir(django):
django.setup()
import django_manage_shell
django_manage_shell.run(PROJECT_ROOT)
Installing IPython and changing the last two lines as below gets it done in the most proper way:
from IPython.core.getipython import get_ipython
ipython = get_ipython()
from django_extensions.management.notebook_extension import load_ipython_extension
load_ipython_extension(ipython)
To make it work: open PyCharm settings (CTRL+S) and head to Django Console section. Then make changes in Starting script window and apply. Finally, start the new Python Console instance.
I looked at the source code of shell_plus, and noticed you could use a method on a Command class named get_imported_objects({})
In PyCharm, go to: Build, Execution, Deployment > Console > Django Console > Starting script
Add this to the existing code in that box:
from django_extensions.management.commands.shell_plus import Command
globals().update(Command().get_imported_objects({}))
Note: you may have to restart PyCharm to see the effect.
One way to solve this is to create a new Python run configuration. Set the target to module, and select the manage.py file for the project. Then put shell_plus in the Parameters field. Set the Working Directory to the project directory. Then lastly, set the Execution to Run with Python Console. Apply the changes, then run the new configuration.
This isn't a complete answer, but I found this script that at least loads up all the app models. Put this in Settings > Console > Django Console > Starting script:
import sys
import logging
logging.basicConfig(format="%(levelname)-8s %(asctime)s %(name)s %(message)s", datefmt='%m/%d/%y %H:%M:%S', stream=sys.stdout )
log = logging.getLogger("root")
from django.db.models import get_models
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
logging.config.dictConfig(settings.LOGGING)
log.debug("Logging has been initialized at DEBUG")
log.setLevel( logging.DEBUG)
log.disabled = False
for _class in get_models():
if _class.__name__.startswith("Historical"): continue
log.debug("Registering model {}".format(_class.__name__))
globals()[_class.__name__] = _class
def debug_sql():
from debug_toolbar.management.commands import debugsqlshell
return
I also submitted this a feature request to JetBrains.
In Django 1.7, following script can be used as a workaround with PyCharm 3.4:
File -> Settings -> Console -> Django Console and manage.py options
In Starting script, put:
import sys
import django
django.setup()
from django.db.models import get_models
for _class in get_models():
globals()[_class.__name__] = _class
This configuration works for me
As django.db.models.get_models no longer exists, here's an updated version that will accomplish the same as Christopher Mason's version.
import sys; print('Python %s on %s' % (sys.version, sys.platform))
import django; print('Django %s' % django.get_version())
import logging
logging.basicConfig(format="%(levelname)-8s %(asctime)s %(name)s %(message)s", datefmt='%m/%d/%y %H:%M:%S', stream=sys.stdout )
log = logging.getLogger("root")
from django.apps import apps
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
logging.config.dictConfig(settings.LOGGING)
log.debug("Logging has been initialized at DEBUG")
log.setLevel( logging.DEBUG)
log.disabled = False
for _configs in apps.get_app_configs():
for _class in _configs.get_models():
if _class.__name__.startswith("Historical"): continue
log.debug("Registering model {}".format(_class.__name__))
globals()[_class.__name__] = apps.get_model(_configs.label, _class.__name__)
def debug_sql():
from debug_toolbar.management.commands import debugsqlshell
return
Related
To run my Django's tests, I was using the manage.py file.
But I decided to create my own file runtests.py.
As specified in the Django's doc, the manage.py file will execute all methods whose name is starting like "test" and whose class inherits TestCase !
My aim is to use this searching method to display all possible tests (not running them).
So do you know where I could get this "searching method" ?
Thank you !
What you're looking for is called "test discovery", and you don't need to do it manually.
If you want to write a standalone script that runs your tests, you can simply invoke Django's test runner manually from Python code after configuring. The process for this is:
# First you need settings.
# You can do this by setting DJANGO_SETTINGS_MODULE:
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'path.to.your.settings')
# Or you can do it manually:
SETTINGS_DICT = {
# Put all the settings you'll need in here...
}
from django.conf import settings
settings.configure(**SETTINGS_DICT)
import django
django.setup()
import sys
# Now you can run tests:
from django.test.utils import get_runner
TestRunner = get_runner(settings)
test_runner = TestRunner(verbosity=2, interactive=True)
failures = test_runner.run_tests(
['test_module_to_look_in']
)
sys.exit(bool(failures))
I got errors while running runtests.py.
I use Ubuntu 16.04 and Django version 1.6.5. I copied code from github.
./runtests.py: line 3: os.environ[DJANGO_SETTINGS_MODULE]: command not found
./runtests.py: line 4: syntax error near unexpected token `(`
./runtests.py: line 4: `test_dir = os.path.dirname(__file__)`
My runtest.py file:
import os
import sys
os.environ['DJANGO_SETTINGS_MODULE'] = 'test-settings'
test_dir = os.path.dirname(__file__)
sys.path.insert(0, test_dir)
import django
from django.test.utils import get_runner
from django.conf import settings
def runtests():
if django.VERSION >= (1, 7):
django.setup()
TestRunner = get_runner(settings)
test_runner = TestRunner(verbosity=1, interactive=True)
failures = test_runner.run_tests(
['quiz', 'essay', 'multichoice', 'true_false']
)
sys.exit(bool(failures))
if __name__ == '__main__':
runtests()
How could I solve these errors?
Looks like you're trying to execute this script on the command line as in ./runtests.py, which is invoking a bash interpreter and hence why you're getting all kinds of weird errors. 2 ways to solve this:
Run it like python runtests.py
Put a shebang at the top of the file #!/usr/bin/env python then run it ./runtests.py.
According to this post you have to change
os.environ['DJANGO_SETTINGS_MODULE'] = 'test-settings'
to
os.environ['DJANGO_SETTINGS_MODULE'] = 'test.settings'
Note
test must be your django project name. If it is not, change it accordingly.
I have this python file tasks.py
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DjangoWebProject.settings')
from django.contrib.auth.models import User
from logreg.models import ActivationCode
import datetime
def remove_users():
print 'hello worldddddddddddddddddddddddddddddddddd'
inactive_users = []
activation_codes = ActivationCode.objects.all()
for activation_code in activation_codes:
if datetime.datetime.date(activation_code.key_expires) < datetime.datetime.date(datetime.datetime.now()):
inactive_users.append(activation_code.user_id)
for inactive_user in inactive_users:
User.objects.filter(id=inactive_user).delete()
But this is in the root folder and when i try to execute it, it gives me the following error
File
"C:\Users\deybala1\AppData\Local\Continuum\Anaconda2\lib\site-packages\dj
ango\apps\registry.py", line 124, in check_apps_ready
raise AppRegistryNotReady("Apps aren't loaded yet.") django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
How do i fix this?
If you're creating any script that is using your django project, it is absolutely necessary to set path to settings of your project before any import from django or your project. And you're importing user model from django in 1st line and model from your project in second.
Also, you will need to call django.setup() first.
To fix that, move import os and setting path to django settings to the very beginning of your script, and put django.setup() just after that (with proper import), like this:
# first, set path to project settings
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DjangoWebProject.settings')
import django
django.setup()
# now you can import anything else
from django.contrib.auth.models import User
from logreg.models import ActivationCode
import datetime
def remove_users():
print 'hello worldddddddddddddddddddddddddddddddddd'
inactive_users = []
activation_codes = ActivationCode.objects.all()
for activation_code in activation_codes:
if datetime.datetime.date(activation_code.key_expires) < datetime.datetime.date(datetime.datetime.now()):
inactive_users.append(activation_code.user_id)
for inactive_user in inactive_users:
User.objects.filter(id=inactive_user).delete()
Note that you're trying to add a settings module inside a script that already requires it.
Wouldn't it be easier if you add a specific django command? Thanks to it you'd be able to start your task with python manage.py --settings=<path_to_your_settings>.
Another tip:
Move every django import statement below
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DjangoWebProject.settings')
While I am working at localhost:8080, when I open interactive console and do some operations, like getting list of Kind etc (address: http://localhost:8080/_ah/admin/interactive) then it gives me this error:
<class 'google.appengine.dist._library.UnacceptableVersionError'>: django 1.2 was requested, but 0.96.4.None is already in use
This errors happened several times, in similar cases. It is stuck until restart localhost by dev_appserver.py
Is this a bug or what I am doing wrong?
Example for what I did at interactive console:
from myapp.models import *
for room in Room.all():
room.update_time = room.create_time
room.put()
Note:
This is my django_bootstrap :
import os
import sys
import logging
import __builtin__
from google.appengine.ext.webapp import util
import pickle
sys.modules['cPicle'] =pickle
logging.getLogger().setLevel(logging.INFO)
sys.path.insert(0, os.path.abspath((os.path.dirname(__file__))))
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from google.appengine.dist import use_library
use_library('django', '1.2')
import django.core.handlers.wsgi
def main():
application = django.core.handlers.wsgi.WSGIHandler()
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
my index.ymal in root folder says:
# AUTOGENERATED
# This index.yaml is automatically updated whenever the dev_appserver
# detects that a new type of query is run. If you want to manage the
# index.yaml file manually, remove the above marker line (the line
# saying "# AUTOGENERATED"). If you want to manage some indexes
# manually, move them above the marker line. The index.yaml file is
# automatically uploaded to the admin console when you next deploy
# your application using appcfg.py.
Thus each time I open http://localhost:8080/_ah/admin/datastore, this file updated: which is still has the same content but timestamp of file on operating system says it is updated.
I think here, As the http://localhost:8080 sees that models.py is not the same then it could load it then can not start django_bootstrap.
However if I first open http://localhost:8080/_ah/admin/datastore and then http://localhost:8080, it works. So this is why sometimes I get error sometimes not: It depends of order urls respective
So I'm very familiar with manage.py test myapp. But I can't figure out how to make my tests.py work as an stand-alone executable. You may be wondering why I would want to do this.. Well I'm working (now) in Eclipse and I can't seem to figure out how to set up the tool to simply run this command. Regardless it would be very nice to simply wrap tests.py in a simple manner to just run that.
Here is what my tests.py looks like.
"""
This simply tests myapp
"""
import sys
import logging
from django.test import TestCase
from django.conf import settings
from django.test.utils import get_runner
class ModelTest(TestCase):
def test_model_test1(self):
"""
This is test 1
"""
self.failUnlessEqual(1 + 1, 2)
def test_model_test2(self):
"""
This is test 2
"""
self.failUnlessEqual(1 + 1, 2)
def test_model_test3(self):
"""
This is test 3
"""
self.failUnlessEqual(1 + 1, 2)
def run_tests():
test_runner = get_runner(settings)
failures = test_runner([], verbosity=9, interactive=False)
sys.exit(failures)
if __name__ == '__main__':
# Setup Logging
loglevel = logging.DEBUG
logging.basicConfig(format="%(levelname)-8s %(asctime)s %(name)s %(message)s",
datefmt='%m/%d/%y %H:%M:%S', stream=sys.stdout)
log = logging.getLogger("")
run_tests()
I think the solution is located on this line but I can't seem to figure out what the first argument needs to be in order for it to magically start working..
failures = test_runner([], verbosity=9, interactive=False)
Thanks for helping!!
**** Updates ****
What I am looking to do (Doh!) is to simply run "myApp" tests. The problem is that this works (and chmod is not the problem) but it wants to run the entire test suite. I don't want that. I just want to run the myApp test suite.
Thanks again!
You could create an "External Tool" configuration for your project, such as:
Location: ${project_loc}/src/${project_name}/manage.py
Working Directory: ${project_loc}/src/${project_name}/
Arguments: test ${string_prompt}
This will run manage.py test <whatever name you type in the string prompt>.
The values above assume that you created a pydev project in Eclipse and then housed your Django project in the pydev src directory. It also assumes that you have the project name for pydev be the same name of your Django project. It will use the currently selected project in the package explorer to determine project_loc and project_name.
a. this should be the first line at your code file (tests.py)
#!/usr/bin/env python
b. run $ chmod +x tests.py