PyCharm doesn't resolve Django apps but the project works - django

This is the project structure generated from having run django-admin startproject school and python manage.py startapp quiz:
In INSTALLED_APPS I've added:
"quiz.apps.QuizConfig",
In order for this project to execute correctly, in school/quiz/views.py I have to import e.g. models from quiz.models instead of the commonly seen school.quiz.models. Otherwise the project fails to run:
As you can see above, PyCharm doesn't recognize quiz. It wants me to use school.quiz instead, but when I do that the project doesn't run:
File "/.../Code/breather/school/school/urls.py", line 19, in <module>
from quiz.views import QuestionView
File "/.../Code/breather/school/quiz/views.py", line 6, in <module>
from school.quiz.models import Question
ModuleNotFoundError: No module named 'school.quiz'
I'd really prefer to use school.quiz, but I can live with using quiz if needed. I just want PyCharm and runserver to reconcile on one way so that I can get on with my project.
These are my Django settings in PyCharm:

You can use "from .models import Question"

Related

Django: settings for tests of a reusable app?

I created a small app in Django and runserver and admin works fine.
I wrote some tests which can call with python manage.py test and the tests pass.
Now I would like to call one particular test via PyCharm.
This fails like this:
/home/guettli/x/venv/bin/python
/snap/pycharm-community/179/plugins/python-ce/helpers/pycharm/_jb_pytest_runner.py
--path /home/guettli/x/xyz/tests.py
Launching pytest with arguments /home/guettli/x/xyz/tests.py in /home/guettli/x
============================= test session starts ==============================
platform linux -- Python 3.6.9, pytest-5.4.1, py-1.8.1, pluggy-0.13.1 --
cachedir: .pytest_cache
rootdir: /home/guettli/x
collecting ...
xyz/tests.py:None (xyz/tests.py)
xyz/tests.py:6: in <module>
from . import views
xyz/views.py:5: in <module>
from xyz.models import Term, SearchLog, GlobalConfig
xyz/models.py:1: in <module>
from django.contrib.auth.models import User
venv/lib/python3.6/site-packages/django/contrib/auth/models.py:2: in <module>
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
venv/lib/python3.6/site-packages/django/contrib/auth/base_user.py:47: in <module>
class AbstractBaseUser(models.Model):
venv/lib/python3.6/site-packages/django/db/models/base.py:107: in __new__
app_config = apps.get_containing_app_config(module)
venv/lib/python3.6/site-packages/django/apps/registry.py:252: in get_containing_app_config
self.check_apps_ready()
venv/lib/python3.6/site-packages/django/apps/registry.py:134: in check_apps_ready
settings.INSTALLED_APPS
venv/lib/python3.6/site-packages/django/conf/__init__.py:76: in __getattr__
self._setup(name)
venv/lib/python3.6/site-packages/django/conf/__init__.py:61: in _setup
% (desc, ENVIRONMENT_VARIABLE))
E 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.
Assertion failed
collected 0 items / 1 error
I understand the background: My app xyz is reusable. It does not contain any settings.
The app does not know (and should not know) my project. But the settings are in my project.
How to solve this?
I read the great django docs, but could not find a solution.
How to set DJANGO_SETTINGS_MODULE if you execute one particular test directly from PyCharm with "Run" (ctrl-shift-F10)?
You can add DJANGO_SETTINGS_MODULE as an environmental variable:
In the menu: Run -> Edit Configurations -> Templates -> Python Tests -> Unittests
And delete old "Unittests for tests...." entries.
You can specify the settings in your test command
Assuming your in the xyz directory, and the structure is
/xyz
- manage.py
- xyz/
- settings.py
The following command should work
python manage.py test --settings=xyz.settings
Edited: For this method to work django support should me enabled in pycharm. I guess it should be possible to setup the equivalent template in the community edition version of pycharm.
Method with django support enabled:
I find that the most convenient way that also allow you to directly click on a particular test case and run it directly within pycharm without having to set the settings every time is to do the following:
->Edit configuration (Run/Debug configurations)
->Templates and select "Django Tests"
->Tick "Custom settings" and then browse to the settings you want use.
Then when you launch tests directly within pycharm it will use it as a template.
If you test with any other supported method by pycharm, you can pick testing framework in pycharm: Choose testing framework
and then create a template for it.
If you use django and pytest, then I recommend the plugin pytest-django
It provides a simple way to set DJANGO_SETTINGS_MODULE via configuration.
See configuring django
[pytest]
DJANGO_SETTINGS_MODULE = test_settings

How to write a stand-alone Python script working with Django modules?

In PyCharm, I created a blank new Django app. Having created some models and issued manage.py makemigrations and manage.py migrate, I tried to write a standalone script that would populate the database with initial data. In its imports I wrote:
from MyApp.models import Model1, Model2, …
Sadly, running this script in PyCharm throws an exception: django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_TABLESPACE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
I Googled this exception, and found an answer in SO https://stackoverflow.com/a/27455703/4385532 advising to put this in the top of my script:
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
So I did. Sadly, this didn’t fix the issue. Now I am greeted with another exception:
django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.
What should I do?
Make sure you also do:
import django
django.setup()
To load your models.
Documentation: https://docs.djangoproject.com/en/1.10/topics/settings/#calling-django-setup-is-required-for-standalone-django-usage

How to run a series of manage.py commands in Django?

I have a Django project. Everytime I deploy, I need to run a series of manage.py command (such as syncdb, south migiration, fixture update).
I am getting tired of type the command line by line and therefore I wrote a python script to do these:
import subprocess
subprocess.call(['python', 'manage.py', 'syncdb'])
#Skip the detail
subprocess.call(['python', 'manage.py', 'loaddata', 'setup/fixture.xml'])
I am wondering if there is a better way to do this?
Thanks.
You can use fabric, a Python library that allows you to script remote actions. This question has some links in the accepted answer for more information on fabric and django.
You can also call management commands directly:
from django.core.management import call_command
call_command('syncdb')
call_command('loaddata', 'setup/fixture.xml')
Save that as a normal python file and execute it from your shell or as part of your deployment scripts.

Eclipse/PyDev/Django Import Requires Project Name

Developing a project in Django with my IDE setup as Eclipse with PyDev. The following import statement:
from polls.models import Poll, Choice
works when running the project from the command line via:
python manage.py runserver
However, built in error-checking with Eclipse fails to find polls.models ("unresolved import Port"). I can fix this by adding the project name before the class and then running this. That is, make the import statement:
from projectName.polls.models import Poll, Choice
The issue is that I'm collaborating on the project and can't do this.
Question is: Is there a way to have Eclipse auto-detect or assume the projectName from the import statement?
Using projectName on import statements is not a good idea.
When working with django/python start to use virtualenv. Especially when working with eclipse/pydev. You can than configure a new interpreter for every virtualenv. Just add the virtualenv to the list of interpreters under "Preferences > PyDev > Interpreter - Python" and be sure to add your djangoproject root to the PYTHONPATH on the same preferences page.
This is essentially what django does for you when running from the command line.

Import all modules in django

In django is there way to import all modules
ex: from project.models import *
ex: from project1.models import *
Can this be done with one statement
If you just want to do this when testing things in the shell, look into the shell_plus command provided by the django-extensions project.
This is a really neat extension, which starts a shell and automatically loads all the models in your project when you do ./manage.py shell_plus from the command line.