I have a python application that uses Django models for easy storage of data. It is NOT a django app, I'm just attempting to use models from django.db, JSONField from django.contrib.postgres.fields and other useful parts.
When I attempt to run python manage.py makemigrations, the terminal stalls. How do I debug this?
Here are some snippets of my code:
manga_shell/models.py
import os, django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "manga_project.settings")
django.setup()
from django.db import models
from django.contrib.postgres.fields import JSONField
class Manga(models.Model):
# fields
class Chapter(models.Model):
# fields
class Page(models.Model):
# fields
manga_project/settings.py
import dj_database_url, os
SECRET_KEY = #secret :P
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
INSTALLED_APPS = (
'django.contrib.postgres',
'manga_shell',
)
DATABASES = {'default': dj_database_url.config(default='postgres://MyUserName:MyPassword#localhost:5432/manga_project_db')}
TIMEZONE = 'Asia/Kolkata'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
If more code is required, I'll post it. I'm not entirely clear on what might cause manage.py to stall, so I don't know for sure which snippets of code are needed. Thanks in advance for the help.
Related
I have all of my Django models in another package which I install using pip in a Django app.
models_package
| - models.py
| - setup.py
and in models.py i have
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
....
in my Django app i have
my_django_app
| ...
| models.py
website
| ...
| settings.py
manage.py
in my_django_app.model i have
from models_package.models import *
and in the website i have added my_django_app as an app (add it to INSTALLED_APP) and in website.settings.py i have
AUTH_USER_MODEL = "my_django_app.User"
but when i run python manage.py runserver i get:
RuntimeError: Model class my_django_app.models.User doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
The Thing is User which comes from models_packages.models and models_packages is not a Django app which I add to INSTALLED_APP in settings.py. it is only a package containing all shared Models that I need in multiple different Django apps.
Is there any way to use models in models_package.models without adding it to INSTALLED_APP inside website.settings.py
i think you need to transform your 'my_django_app' to a django app:
all you need to do is to add app.py inside my_django_app package
from django.apps import AppConfig
class ApiConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'my_django_app'
then you can add it to your INSTALLED_APP
I have a Django project with an application called application.
The app is installed in the INSTALLED_APPS as follows:
### application/settings.py
INSTALLED_APPS = [
...
'application.apps.MyAppConfig',
]
with the AppConfig:
### application/apps.py
class MyAppConfig(AppConfig):
name = 'application'
verbose_name = 'My App'
label = 'application'
path = f"{os.environ.get('APP_DIR')}/application"
default = True
I have the models defined like this:
### data/models/basemodel.py
from django.db import models
class MyBaseModel(models.Model):
# ... fields ...
Meta:
app_label: `application`
Project's tree:
main_dir/
data/
__init__.py
models/
__init__.py
basemodel.py
application/
__init__.py
apps.py
urls.py
settings.py
...
Django is not finding the models, and if I run makemigrations Django responds No changes detected, and on migrate, the app application does not appear on the Operations to perform.
I want to split the data layer from the logic and interface layers. In order to do so, I've the models and other data-related business inside data (outside any installed app)
The goal is to link the models to the app from there, without having to declare any model inside the application dir.
The Model should be detected so the Django detects migrations to apply.
Context:
Django Application reference: doc
Django Models reference: doc
I guess you want to have a single module per model ? If so, you need to import your models inside models\__init__ like so:
from .basemodel import BaseModel
I also suggest that you define __all__ inside your init file, in order to import your models easily in other parts of the app:
__all__ = ["BaseModel"]
from .basemodel import BaseModel
At work we are using django-admin webapp. I wanted to implement django-ajax-selects functionality to some of fields. Our network is isolated from Internet and I cannot use django-ajax-selects's CDNs. Documentation says that in such case you should set AJAX_SELECT_BOOTSTRAP to False in settings.py file. However, when I set this parameter, django-ajax-selects fails to use django's jquery.
Django's version is 1.11.10, Python2.
Steps to reproduce my issue:
pip install django==1.11.10 django-ajax-selects
django-admin startproject proj ./
python manage.py startapp test_app
python manage.py migrate
python manage.py createsuperuser
test_app/models.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
class Tag(models.Model):
name = models.CharField(max_length=100)
something = models.CharField(max_length=100)
def __str__(self):
return self.name
class SecondModel(models.Model):
name = models.CharField(max_length=200)
tag = models.ForeignKey(Tag, on_delete=models.CASCADE)
def __str__(self):
return self.name
test_app/lookups.py
from ajax_select import register, LookupChannel
from .models import Tag
#register('tags')
class TagsLookup(LookupChannel):
model = Tag
def get_query(self, q, request):
return self.model.objects.filter(name__icontains=q)
def format_item_display(self, item):
return u"<span class='tag'>%s</span>" % item.name
test_app/admin.py
# -*- coding: utf-8 -*-
from django.contrib import admin
from ajax_select import make_ajax_form
from .models import Tag, SecondModel
#admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
fields = ['name', 'something']
#admin.register(SecondModel)
class SecondModelAdmin(admin.ModelAdmin):
form = make_ajax_form(SecondModel, {
'tag': 'tags'
})
proj/settings.py - adding the app and ajax_select to INSTALLED_APPS
INSTALLED_APPS = (
...
'ajax_select',
'test_app',
)
proj/urls.py
from django.conf.urls import url, include
from django.contrib import admin
from ajax_select import urls as ajax_select_urls
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^ajax_select/', include(ajax_select_urls)),
]
Then
python manage.py makemigrations test_app
python manage.py migrate
If I run the server like that it works absolutely fine (because it uses CDNs to load jquery and stuff).
But if I set AJAX_SELECT_BOOTSTRAP to False I will get a TypeError in browser's console and the ajax functionality will not work. I guess ajax_select.js just loads before django's jquery was loaded. I could not figure it out, how can I specify load order or may be there is another way? Template overriding would be not very good idea as there is some overriding already used by other apps and I'm afraid it can cause some conflicts.
In the end what I needed to do was to manually download jquery.min.js, jquery-ui.js, jquery-ui.css and also jquery-ui images library, put them into app's static directory and point to them in admin.py:
admin.py
...
#admin.register(SecondModel)
class SecondModelAdmin(admin.ModelAdmin):
form = SecondModelForm
class Media:
js = ["/static/js/jquery.min.js",
"/static/js/jquery-ui.js"]
css = {'all': ["/static/css/jquery-ui.css"]}
Also don't forget to run python manage.py collectstatic for static files to be copied to common static directory.
Stumbled upon something very weird today.
I created a minimal project/application that can show the issue. This is how I did it:
virtualenv venv
. ./ven/bin/activate
pip install django==1.6 # That's the one we're using
django-admin.py startproject bla
cd bla
chmod +x manage.py
./manage.py startapp bla_app
in bla/settings.py:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bla_app',
)
AUTH_USER_MODEL = 'bla_app.MyUser'
in bla_app/models.py:
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class MyUser(AbstractUser):
super_name = models.CharField(max_length=254, unique=True)
Then, I run the syncdb command:
./manage.py syncdb
And it's been created as expected.
Now comes the tricky part. If I replace the models.py with a folder called models, and create an __init__.py file containing:
from my_user import MyUser
(the previous models.py was moved into models/ as my_user.py)
I then get these errors:
$ ./manage.py syncdb
CommandError: One or more models did not validate:
admin.logentry: 'user' has a relation with model bla_app.MyUser, which has either not been installed or is abstract.
auth.user: Model has been swapped out for 'bla_app.MyUser' which has not been installed or is abstract.
Do you have an idea of what is going on here?
I found that, but I'm not sure they're related
Django expects your model classes to be defined in models.py itself, not in a submodule. It's going to try to create an instance of models.MyUser which in your case does not exist in Django's world even though you've defined it in my_user.py
If you're looking to define each model in a separate Python file, you'd need to create a models.py file that imports them manually. This will likely be hard to maintain if you start creating a lot of models in that app.
app/
__init__.py
models.py
_models/
__init__.py
my_user.py
In models.py
from ._models.my_user import MyUser
To split your model into modules, you have to provide the app_label Meta Option. Ex:
my_user.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class MyUser(AbstractUser):
super_name = models.CharField(max_length=254, unique=True)
class Meta:
app_label = 'bla_app'
As #petkostas said, it will not be required in Django 1.7 (issue 4470)
Take a look at this answer, which describes the process.
I would like to create a User model that has an additional couple fields in django. I tried to do so by following the advice
https://stackoverflow.com/a/22696794/3426600 to create a custom user model
in models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
user_data = models.TextField(null=True)
In settings.py
AUTH_USER_MODEL = 'app_name.User'
but when I run python manage.py syncdb
I get the errors:
CommandError: One or more models did not validate:
account.emailaddress: 'user' has a relation with model app_name.User, which has either not been installed or is abstract.
admin.logentry: 'user' has a relation with model app_name.User, which has either not been installed or is abstract.
auth.user: Model has been swapped out for 'app_name.User' which has not been installed or is abstract.
socialaccount.socialaccount: 'user' has a relation with model app_name.User, which has either not been installed or is abstract.
Could I be using the wrong app_name? If so, where do I find the app_name?
How do I make the custom user work with socialaccount, etc?
Assume your project strucutre is something like below, and the codes of User(AbstractUser) are located in mysite/mysite/app1/models.py:
mysite/ (root folder for the project, put it anywhere in your disk. Most developers have a workspace folder(s) in computer)
(other non-application things. E.g. a static/, README.md, ...)
manage.py
mysite/ (container for all applications. You can put applications directly under root folder, but not recommended)
__init__.py
settings.py
urls.py
wsgi.py
app1/ (each application resides in its own folder. You don't want to put all models in one models.py file or all views in one view.py file, right?)
__init__.py
models.py
views.py
......
Then the app_name is app1, i.e. AUTH_USER_MODEL = 'app1.User'. Meanwhile, you need to add mysite.app1 into INSTALLED_APPS in settings.py. This probably will solve you CommandError issue.
ADDED NOTES:
Each application, you can consider it as a module of your project. The app_name of the application is the folder name. If you have defined models in one application, must add it into INSTALLED_APPS in settings.py.
Manually creating a folder is not a good way. django-admin.py startapp is more recommended, because it together creates some common files for an application, e.g. init.py, models.py, view.py, ...
Suggest you to go through the django quick-start guide, if you haven't done it: https://docs.djangoproject.com/en/dev/intro/tutorial01/