Django custom AppConfig breaks the project - django

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?

Related

Trouble with routing in django - page not found

I am not able to perform routing.
error at /home:
[enter image description here]
urls.py:
from django.contrib import admin
from django.urls import path
from app.views import views
urlpatterns = [
path('home/', views.home_view, name='home'),
path('admin/', admin.site.urls),
]
views.py:
from django.http import HttpResponse
from django.shortcuts import render
def home_view(*args, **kwargs):
return HttpResponse("<h1>Hello World<h1>")
From the limited information (at the time of writing this answer) provided by OP, it seems the django app app is not registered in INSTALLED_APPS
From the images, it seems the project is structured like this
project/
├── app
│   ├── __init__py
│   └── views.py
├── asgi.py
├── __init__.py
├── manage.py
├── settings.py
├── urls.py
└── wsgi.py
You need to add app in the INSTALLED_APPS list in your settings.py
INSTALLED_APPS = [
...
'app',
...
]
This activates your sub-app app to be used in your django project.
the import in urls.py should be
from app import views
but it is difficult to judge without the full error message

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 - tests.py already exists, overlaying a project or app into an existing directory won't replace conflicting files

In my project I'm using Django 1.9. I started this project on older version of Django. After update everything works fine. But now I need to install new app but i can't. When i try to do this i get an error:
CommandError: /var/www/myproject/myapp/tests.py already exists, overlaying a project or app into an existing directory won't replace conflicting files.
After that i tried to record my app in INSTALLED_APPS, and then i go an error: ImportError: No module named myapp.
Here is full traceback of this error:
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 353, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 327, in execute
django.setup()
File "/usr/local/lib/python2.7/dist-packages/django/__init__.py", line 18, in setup
apps.populate(settings.INSTALLED_APPS)
File "/usr/local/lib/python2.7/dist-packages/django/apps/registry.py", line 85, in populate
app_config = AppConfig.create(entry)
File "/usr/local/lib/python2.7/dist-packages/django/apps/config.py", line 90, in create
module = import_module(entry)
File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
ImportError: No module named myapp
So delete django using pip, and then install again. But i have still the same problem.
At the first time my Installed Apps looks like this:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'firstapp',
'secondapp',
'thirdapp',
)
but after Django updating i change:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'firstapp',
'secondapp',
'thirdapp',
]
Here is layout files of my project:
project
├── firstapp
│ ├── __init__.py
│ ├── models.py
│ ├── admin.py
│ ├── views.py
│ ├── forms.py
│ ├── urls.py
├── secondapp
│ ├── __init__.py
│ ├── models.py
│ ├── admin.py
│ ├── views.py
│ ├── urls.py
├── thirdapp
│ ├── __init__.py
│ ├── models.py
│ ├── admin.py
│ ├── views.py
│ ├── urls.py
├── project
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
├── manage.py
You surely have fixed your issue by now, but I wanted to put a fix up for anyone else that comes across this.
I had the same issue (also caused after an upgrade to 1.9), and found that I couldn't even run django-admin startproject without a similar error when using the same virtualenv.
I created a new virtualenv and then ran pip install -r requirements.txt to load all the project's required packages. I could then create apps without a problem.
I compared the two virtualenv site-packages directories, but saw no glaring differences. Either way, this worked to fix my issue.

django module import error - python 2.7 vs python 3.4

I have installed django1.9 with python 2.7. But now I want to use it with python3.4. Hence I have modified symbolic link of python to python 3.4 like below.
sudo ln -s /usr/bin/python3.4 /usr/bin/python
Because same django works with python 2.7 and 3.4 as well so it should work. But now if I run ./mange.py runserver I am getting below error. But with Python 2.7 the same code works properly.
from Helpers import views
ImportError: No module named 'Helpers'
Please let me know whats wrong there? Below are the project structure.
myproject
├── myproject
│ ├── settings.py
│ ├── __init__.py
│ ├── urls.py
│ ├── wsgi.py
│ └─── Helpers
│ ├── views.py
│ └── __init__.py
└── manage.py
Urls.py is like below.
from django.conf.urls import url
from Helpers import views
urlpatterns = [
url(r'^$', views.index, name='index')
]
setting.py contains below relevant information.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myproject',
]
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Look for modules here as well.
sys.path.insert(0, os.path.join(BASE_DIR, "Helpers"))
Any idea?
Python 3 has changed the import policy. Take a look at this question.
Instead of adding Helpers directory to sys.path, add it's parent:
sys.path.insert(0, os.path.join(BASE_DIR, 'myproject'))
Or like #albar mentioned - use relative import:
from .Helpers import views