Django 2.0 Access Models (CREATE/REMOVE/FILTER) Standalone [without manage.py shell]


Django 2.0 Access Models (CREATE/REMOVE/FILTER) Standalone [without manage.py shell]



I have a Django project and I wanted to generate some objects (from the models)



What I'm trying to get at : Standalone Python Script to create bunch of objects and/or filter,delete.



after importing the model with from apps.base.models import MyModel
and setting up the configuration as the previous StackOverflow Questions suggested I was not able to run the script.


from apps.base.models import MyModel


import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myProject.settings")
import django

django.setup()
from apps.base.models import MyModel



Please note that this is on Django version 2.0.6 [Django 2.0+].



Correct settings have been used, (i.e. myProject.settings)


myProject.settings



After properly configuring everything else I get the following error:


RuntimeError: Model class apps.base.models.MyModel doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.



Settings:



base.py : https://pastebin.com/MNcitE4U



development.py : https://pastebin.com/JAHqxwRM



The full GitHub link is here: https://github.com/teratzu/Razred-Management



The current answer(s) are out-of-date and require revision given recent changes.



I'm looking for the correct answer, All the answers are outdated and do NOT work for Django 2.0 Which is the most current version of Django available. The issue presents itself when trying to load the models from the models.py, I do have multiple .settings... but that shouldn't be an issue since everything else is configured properly.





make sure you have this script in this path project -> scripts -> script.py
– Ojas Kale
Jun 28 at 18:07





ModuleNotFoundError: No module named 'MyProject'// This would be after moving it to a /script/script.py
– Elvir Muslic
Jun 28 at 18:29



ModuleNotFoundError: No module named 'MyProject'





Could you add your project's settings.py, particularly INSTALLED_APPS, and the directory layout of your project?
– Cole
Jul 2 at 3:27


settings.py


INSTALLED_APPS





Did you add your app name to INSTALLED_APPS? Can you share myproject.settings module?
– hoefling
Jul 2 at 9:23


INSTALLED_APPS


myproject.settings





Also, the import looks suspicious, I also suggest you show the project directory structure.
– hoefling
Jul 2 at 9:26




3 Answers
3



I git clone'd your Django project's repository and got it working doing the following:


git clone



1. Move your Project's apps to the root of the project



This is a common Django standard. What I did was ./manage.py startapp base to start fresh and then add all of the files/directories from the apps/base directory to the base directory that was just made. It should look like this in the root directory of your project (where DzenanElvir & base are directories):


./manage.py startapp base


apps/base


base


DzenanElvir


base


(.env) Cole:StackOverflow/Razred-Management ‹master*›$ ls -l
total 512
drwxr-xr-x 9 Cole staff 288 Jul 2 23:50 DzenanElvir
-rw-r--r-- 1 Cole staff 1055 Jul 2 23:48 LICENSE
-rw-r--r-- 1 Cole staff 299 Jul 2 23:48 Pipfile
-rw-r--r-- 1 Cole staff 27343 Jul 2 23:48 Pipfile.lock
-rw-r--r-- 1 Cole staff 72 Jul 2 23:48 Procfile
-rw-r--r-- 1 Cole staff 1160 Jul 2 23:48 README.md
drwxr-xr-x 15 Cole staff 480 Jul 3 00:06 base
...



And like this in your new base app directory:


base


(.env) Cole:Razred-Management/base ‹master*›$ ls -l
total 80
-rw-r--r-- 1 Cole staff 53 Jul 2 23:58 __init__.py
drwxr-xr-x 11 Cole staff 352 Jul 3 00:08 __pycache__
-rw-r--r-- 1 Cole staff 63 Jul 3 00:04 admin.py
-rw-r--r-- 1 Cole staff 83 Jul 3 00:04 apps.py
-rw-r--r-- 1 Cole staff 2004 Jul 2 23:58 forms.py
drwxr-xr-x 5 Cole staff 160 Jul 3 00:06 migrations
-rw-r--r-- 1 Cole staff 1126 Jul 2 23:58 models.py
-rw-r--r-- 1 Cole staff 2236 Jul 2 23:58 postsView.py
-rw-r--r-- 1 Cole staff 1913 Jul 2 23:58 pregledView.py
drwxr-xr-x 3 Cole staff 96 Jul 2 23:58 templates
-rw-r--r-- 1 Cole staff 60 Jul 3 00:04 tests.py
-rw-r--r-- 1 Cole staff 1425 Jul 2 23:58 urls.py
-rw-r--r-- 1 Cole staff 343 Jul 2 23:58 views.py



2. Add base app to INSTALLED_APPS the more explicit way


base


INSTALLED_APPS



Notice the new base/apps.py file, we're going to use it's AppConfig-based class to declare it an installed app. Replace INSTALLED_APPS's 'base' declaration with 'base.apps.BaseConfig'.


base/apps.py


AppConfig


INSTALLED_APPS


'base'


'base.apps.BaseConfig'



3. Rework your settings.BASE_DIR variable


settings.BASE_DIR



Typically, the file path to a Django project's settings file is projectname/settings.py but for separated settings it's projectname/settings/<env_name>.py.


projectname/settings.py


projectname/settings/<env_name>.py



Therefore, BASE_DIR needs to be reworked from:


BASE_DIR


BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))



to:


BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))



to account for the extra directory between your project root and your settings file.



4. Migrate models



Perform ./manage.py makemigrations && ./manage.py migrate.


./manage.py makemigrations && ./manage.py migrate



Also, as a side-note, migrations directories shouldn't be in .gitignore. Read: Should I be adding the Django migration files in the .gitignore file?


migrations


.gitignore





And with that I was able to run the below script, at the root of the Django project, without error:


import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "DzenanElvir.settings.base")
import django

django.setup()
from base.models import ModelRazred





Sorry, I don't want the project structure reworked. What's the solution to get it working on the already existing project?
– Elvir Muslic
2 days ago





@ElvirMuslic I've added another solution without involving a project structure rework, although I advise against creating non-reusable apps.
– Cole
2 days ago




I see two issues in the current project structure.


AppConfig



As the other answer suggested correctly, you need to provide an AppConfig subclass to register your application; see Configuring applications section in Django docs.


AppConfig



However, having an apps package for namespace declarations is totally fine, especially if you plan to have multiple apps; in fact, this is what Django does itself, bundling all batteries apps under the django.contrib namespace. At my work, we also use common namespaces to organize Django apps: mycompany.internal.someapp, mycompany.customers.otherapp etc.


apps


django.contrib


mycompany.internal.someapp


mycompany.customers.otherapp



So you don't need to move the files. Just reference the apps.base correctly: create a file apps/base/apps.py with the content:


apps.base


apps/base/apps.py


# apps/base/apps.py
from django.apps import AppConfig


class MyBaseAppConfig(AppConfig):
name = 'apps.base'



Now reference the created config class of the app apps.base in the settings:


apps.base


# DzenanElvir/settings/base.py

INSTALLED_APPS = [
...
# Local apps
'apps.base.apps.MyBaseAppConfig',
]


apps



So you declared the apps package (by placing an__init__.py file in the apps dir). However, you never use the package, instead fiddling the sys.path by adding the apps dir to it. If the app should be importable under apps.base, remove the path fiddling line in the DzenanElvir/settings.base.py:


apps


__init__.py


apps


sys.path


apps


apps.base


DzenanElvir/settings.base.py


# remove this line:
path.append(os.path.join(PROJECT_ROOT, "apps"))



and use the right imports throughout the app, replacing:


from .models


from apps.base.models


from .forms


from apps.base.forms


from .pregledView


from apps.base.pregledView


from .postsView


from apps.base.postsView



Also, don't forget to replace


urlpatterns = [
url(r'', include('base.urls')),
...
]



with


urlpatterns = [
url(r'', include('apps.base.urls')),
...
]



in DzenanElvir/urls.py and you should be good to go.


DzenanElvir/urls.py





The Django package isn’t a Django project itself, contrib is simply a directory of reusable Django apps to solve common Web-development problems (as it says in the docs, docs.djangoproject.com/en/2.1/ref/contrib).
– Cole
Jul 3 at 16:21


contrib





The Django package isn’t a Django project itself - I never said that. contrib is simply a directory of reusable Django apps - in fact, contrib is a python package that is an example of how to bundle multiple Django apps under a single package. You do realize that startproject and startapp are just handy shortcuts for creating an initial project structure, nothing more? And that you can develop Django apps without creating a Django project, having an app that is the project or just have multiple apps in the same codebase?
– hoefling
Jul 3 at 16:55


contrib


startproject


startapp





I was under the impression that the justification from, "... having an apps package for namespace declarations is totally fine, especially if you plan to have multiple apps; in fact, this is what Django does itself ..." inferred that the Django Python package is a Django project because it puts its reusable (and not installed) apps in a directory. I was simply pointing out that Python package != Django project's apps, so the Django package doesn't actually do that. Maybe I misinterpreted what you said
– Cole
Jul 3 at 19:00



I've once again git clone'd your Django project's repository and got it working, without having to rework your project's structure, by doing the following:


git clone



1. Rework your settings.BASE_DIR variable


settings.BASE_DIR



Typically, the file path to a Django project's settings file is projectname/settings.py but for separated settings it's projectname/settings/<env_name>.py.


projectname/settings.py


projectname/settings/<env_name>.py



Therefore, BASE_DIR needs to be reworked from:


BASE_DIR


BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))



to:


BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))



to account for the extra directory between your project root and your settings file.



2. Change app declaration in INSTALLED_APPS:


INSTALLED_APPS



Your app's dotted location from BASE_DIR is apps.base. Replace the current declaration, base, with apps.base.


BASE_DIR


apps.base


base


apps.base



3. Migrate models



Perform ./manage.py makemigrations && ./manage.py migrate.


./manage.py makemigrations && ./manage.py migrate



Also, as a side-note, migrations directories shouldn't be in .gitignore. Read: Should I be adding the Django migration files in the .gitignore file?


migrations


.gitignore





And with that I was able to run the below script, at the root of the Django project, without error:


import os
import django

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "DzenanElvir.settings.base")
django.setup()
from apps.base.models import ModelRazred





When I try to change the BASE_DIR I get : ModuleNotFoundError: No module named 'base' and if I change the base to apps.base I get : RuntimeError: Model class base.models.ModelRazred doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
– Elvir Muslic
2 days ago


ModuleNotFoundError: No module named 'base'


base


apps.base


RuntimeError: Model class base.models.ModelRazred doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.





It might be caused by other things using dotted path. Check the traceback. Other than that, I don't know what to tell you – the standalone script works on my end
– Cole
yesterday






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

How to add background colour in existing image using Swift?

Moria Casán

How to make file upload 'Required' in Contact Form 7?