Where is the Django migrations folder? - django

I must be doing something wrong. Everywhere I see people saying "Look at the migrations folder" but even though I can see migrations there is no folder.
Karls-Mac-mini:django_test karl$ tree
├── django_test
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-35.pyc
│   │   ├── settings.cpython-35.pyc
│   │   └── urls.cpython-35.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py
Karls-Mac-mini:django_test karl$ python manage.py showmigrations
admin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
[X] 0003_logentry_add_action_flag_choices
auth
[X] 0001_initial
[X] 0002_alter_permission_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
[X] 0005_alter_user_last_login_null
[X] 0006_require_contenttypes_0002
[X] 0007_alter_validators_add_error_messages
[X] 0008_alter_user_username_max_length
[X] 0009_alter_user_last_name_max_length
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
sessions
[X] 0001_initial

Short answer: the migrations originate from Django apps and third party apps you installed in INSTALLED_APPS. Not the ones you defined yourself.
Migrations are generated per app, and are stored in some_app/migrations.
Even if you do not define migrations for your apps, there will usually be migrations that take place, since you (likely) included some apps defined by Django (and other third parties) in your INSTALLED_APPS, these have migrations as well.
For example most likely your INSTALLED_APPS contains:
# settings.py
INSTALLED_APPS = [
# ...
'django.contrib.auth',
# ...
]
If we take a look at the source code of this app [GitHub], we see the migrations directiory. By adding this app to the INSTALLED_APPS you thus have added apps defined in the Django library itself (or by third parties) to your project, and the migrations of these apps are thus processed in the same way (in fact there is nothing "magical" about these apps, it is more that these handle common problems such that you do not need to care about these anymore).
The django.contrib.auth app has a file structure like (ommitting noise):
django/
contrib/
auth/
migrations/
__init__.py
0001_initial.py
0002_alter_permission_name_max_length.py
0003_alter_user_email_max_length.py
0004_alter_user_username_opts.py
0005_alter_user_last_login_null.py
0006_require_contenttypes_0002.py
0007_alter_validators_add_error_messages.py
0008_alter_user_username_max_length.py
0009_alter_user_last_name_max_length.py
These are extactly the same migrations you see on the console when you perform migrations for the auth app (second section).

Django Project is actually a combination of a few Applications and Configuration files.
Applications and Configuration are actually Python Modules/Packages. Every project has a few default apps installed and they are mentioned in INSTALLED_APPS (see project settings.py).
These are the default apps and they are not stored/installed in your project: they reside inside Django package by default.
Example:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
For example, django.contrib.admin app is used with your application: the migrations directory for this app is available at site-packages/django/contrib/admin/migrations, but migrations from apps that you created, are all stored inside each app folder.

Related

Django custom AppConfig breaks the project

I've got a bare-bones demonstration Django project created with Django 2.2. The structure looks like:
my_project/
├── db.sqlite3
├── my_app
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── models.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── my_project
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── requirements.txt
This started as a tiny issue: "my_app" was showing up in the Django admin as "MY_APP" (with an underscore). The Django docs say that you can make this prettier by defining a custom app config that subclasses "django.apps.AppConfig", and that typically this subclass would be defined in (using my example) "my_app/apps.py". In fact, using manage.py startapp my_app even generates this for you:
# my_app/apps.py
from django.apps import AppConfig
class MyAppConfig(AppConfig):
name = 'my_app'
The docs also say to "put the dotted path to that subclass in INSTALLED_APPS". Another approach is to set the default_app_config variable in your app's "__init__.py", but that "New applications should avoid default_app_config. Instead they should require the dotted path to the appropriate AppConfig subclass to be configured explicitly in INSTALLED_APPS."
However, if I do add the path to the custom app config into INSTALLED_APPS like this:
# settings.py
...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'my_app',
'my_app.apps.MyAppConfig'
]
...
the project immediately crashes with "LookupError: No installed app with label 'admin'."
The error traces back to the reference to admin.site.urls in the project's root "urls.py" (line 6 below):
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('my_app/', include('my_app.urls', namespace='my_app'))
]
In conclusion, adding the path to the "apps" module created by "startapp" -- even without
making any changes to that module -- crashes the project. OTOH if I go against the docs' advice and define default_app_config in "my_app/init.py", that does work.
This seems very basic, but Googling it is turning up nothing, which usually means I'm making some fundamental error that I don't realize. Any ideas, anyone?

Django static files in production not loaded

I have a problem with static files in my Django application.
I create a simple blog app with Django REST Framework and Angular 6. It's working fine in my local development environment, but I have a problem with deploying it to production. The thing is, the app is loading (I know that because the root route is a redirection to /app and I am being redirected correctly) but there are no static files loaded.
Here is part of my configuration related to the static files:
STATIC_URL = '/static/'
BASE_DIR = os.path.join(
os.path.dirname(os.path.dirname(__file__)), '..', '..', '..'
)
STATIC_ROOT = os.path.join(BASE_DIR, 'app', 'static')
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'frontend'),
]
INSTALLED_APPS = [
...
'django.contrib.staticfiles'
...
]
The paths are correct, I triple-checked them to be sure. And here are routes configured in Django application:
urlpatterns = [
url('^api/', include(api_patterns)),
url('^admin/', admin.site.urls),
url('^app/', serve, kwargs={'path': 'index.html'}),
url('^$', HomepageView.as_view(), name='homepage-redirection'),
]
I am able to run manage.py collectstatic without any errors and all static files are correctly copied to the static directory. Static files for admin application are not loaded correctly as well. Here is a rough structure of directories in my project:
├── app
│   └── (python code here)
├── frontend
│   └── (angular code here)
├── media
│   └── (empty for now)
└── static
  └── (static files for Django)
The application server is nginx with Phusion Passenger (this was configured by my the company I rent the server from). I don't really know what else I can add here. Does anyone have any idea what can be wrong here? Maybe some hint would be the fact that the API endpoints are not accessible. I have access to admin application, but not to API (both configured in the same urls file).

Reference 'django.contrib.auth.urls' to custom specific templates

I wrote specific templates to deal with password reset and change,
the file tree structures as:
In [3]: !tree /Users/me/desktop/Django/forum/user/templates
/Users/me/desktop/Django/forum/user/templates
├── registration
│   ├── logged_out.html
│   ├── login.html
│   ├── password_change_done.html
│   ├── password_reset_complete.html
│   ├── password_reset_confirm.html
│   ├── password_reset_done.html
│   └── password_reset_form.html
└── user
├── activate.html
├── failure.html
├── register.html
├── success.html
└── validate.html
The project urls is configured as:
# Project url
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r"^$", views.index, name="index"),
url(r'^article/', include('article.urls',namespace='article')),
url(r'^user/', include('user.urls',namespace='user')),
url(r'^user/', include('django.contrib.auth.urls')),
]
Unfortunately, when I try to issue request as http://127.0.0.1:8001/user/password_reset/,
the browser redirect to its default admin site
I am working on Django 1.11
How reference 'django.contrib.auth.urls' to my own templates?
If you just want to override admin templates, you can just add admin directory and templates in your template dir.
It's well explained in django official docs (https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-admin-templates)
If you want to override view either, you have to make your own app and match it to urls.
You can also pass template_name as variable...:
in urls.py:
from django.contrib.auth import views as auth_views
urlpatterns = [
url(r'^user/login-custom-template/$', auth_views.login, {'template_name': 'path-to-custom-template.html'}, name='login-custom'),
]
To ref to your template, in case it doesn't work just use template name:
urlpatterns = [
path(
'change-password/',
auth_views.PasswordChangeView.as_view(template_name='change-password.html'),
),
]
OR:
Even skip django.contrib.auth.urls if you want to use another directory template not in registration, in this case I point to template /basic_app/
from django.contrib.auth import views as auth_views
AND
re_path(r'^login/$',auth_views.LoginView.as_view(template_name='basic_app/login.html'),name='login')
Analyzing the same problem while doing this tutorial:
I discovered that You can skip 'admin' route described earlier and just move Your users app above other apps in settings:
INSTALLED_APPS = [
'users',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# External apps
'taggit',
# My apps
'projekty',
'blog',
]

Problems getting Django/Apache2/mod_wsgi configured without having extra component in URL

What I'm trying to accomplish is to have Apache serve all content at mysite.com/ and have Django handle everything under mydomain.com/signup and mydomain.com/login.
The problem is that right now the user has to browse to mydomain.com/mysite/signup or mydomain.com/mysite/login for things to work. I want to get rid of the mysite part of the URLs.
I created a project with
django-admin startproject signup mysite
cd mysite
django-admin startapp login
I ended up with this directory structure.
mysite
├── login
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── manage.py
└── signup
├── __init__.py
├── settings.py
├── urls.py
├── views.py
└── wsgi.py
I have the following urlpatterns in signup/urls.py
urlpatterns = [
url(r'^signup/', views.index, name='index'),
url(r'^login/', include('login.urls')),
url(r'^admin/', admin.site.urls),
]
I have Apache mod_wsgi installed and working and have this WSGIScriptAlias in my virtual host file.
WSGIScriptAlias /mysite /usr/local/www/wsgi-scripts/mysite/signup/wsgi.py process-group=mysite.com
When the user goes to either mydomain.com/mysite/signup or mydomain.com/mysite/login everything works.
What I want to do is get rid of the 'mysite' part of the above URLs so the user just has to browse to mydomain.com/signup or mydomain.com/login.
I've tried
WSGIScriptAlias /signup /usr/local/www/wsgi-scripts/mysite/signup/wsgi.py process-group=mysite.com
WSGIScriptAlias /login /usr/local/www/wsgi-scripts/mysite/signup/wsgi.py process-group=mysite.com
But that doesn't work because either Apache or mod_wsgi strips off the 'signup' or 'login' part before it gets to Django and Django just thinks the user is looking for '/'.
Any suggestions?
Thanks
Try using:
WSGIScriptAlias /signup /usr/local/www/wsgi-scripts/mysite/signup/wsgi.py/signup process-group=mysite.com application-group=%{GLOBAL}
WSGIScriptAlias /login /usr/local/www/wsgi-scripts/mysite/signup/wsgi.py/login process-group=mysite.com application-group=%{GLOBAL}
Note how the mount point is added after wsgi.py. The application-group option is also added to ensure you only get one instance of your Django application in the process.
The other way is for any static files to be handled by Apache, with everything else handled by the WSGI application. How to do this is documented towards end of section 'The Apache Alias Directive' in:
http://modwsgi.readthedocs.io/en/develop/user-guides/configuration-guidelines.html#the-apache-alias-directive
If you don't want a prefix, don't use one.
WSGIScriptAlias / /usr/local/www/....

Django.staticfiles doesn't collect admin files

I noticed that staticfiles doesn't copy the admin's static files to STATIC_ROOT. I was under the impression (and I can't find references for that just now) that once you include django.contrib.staticfiles to your INSTALLED_APPS, it would automatically copy admin's static files (as well as all the other ones). However, it doesn't seem to be the case.
From browsing a dozen related questions on SO it seems that the accepted way is to include the hardcoded path to your virtualenv'd admin path to your NGINX, such as here:
location /static/admin {
root /webapps/hello_django/lib/python2.7/site-packages/django/contrib/admin/;
}
However, this seems rather dirty to me.
I should also mention that finders are working for me, i.e.
$ ./manage.py findstatic admin
Found 'admin' here:
/<path to venv>/lib/python2.7/site-packages/django/contrib/admin/static/admin
Am I missing something here?
Check if you have all settings set like that in your settings.py.
I suppose that your static files are under static dir in your project root folder.
import os
import sys
STATIC_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static/')
STATIC_URL = '/static/'
ADMIN_MEDIA_PREFIX = '/static/admin/'
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
INSTALLED_APPS = (
# default apps
'django.contrib.staticfiles',
# etc
)
STATICFILES_DIRS = ()
nginx config:
location /static {
alias /path_to_your_project/static;
access_log off;
expires max;
}
Turns out there was a subtle problem with my settings.py splitting method. For anyone coming here from Google, I was following deploydjango.com's and strategy on splitting settings.py, however ROOT_DIR was being defined in terms of the project, i.e. the following structure
$ tree -L 2
.
├── static
├── apps
└── project
├── __init__.py
├── settings
│   ├── __init__.py
│   ├── base.py
│   ├── dev.py
│   └── prod.py
├── urls.py
└── wsgi.py
with the following setting
STATICFILES_DIRS = (
ABS_PATH('apps', 'example_app', 'static'),
)
would result in ROOT_DIR being set to project/. And since ABS_PATH function defines paths based on ROOT_DIR, the apps/ folder is not visible (it should be preceded with '..').
The solution is of course to move apps/ folder inside the project/ folder, which makes sense. I.e. the correct structure is as follows:
$ tree -L 2
.
├── static
└── project_name
├── __init__.py
├── apps # <-- apps moved here
│   └── example_app
├── settings
│   ├── __init__.py
│   ├── base.py
│   ├── dev.py
│   └── prod.py
├── urls.py
└── wsgi.py
I realised this problem is very tied to the way I was doing things, however since this structure can be seen by some people as "best practice" (although some disagree), I hope this helps someone!