I'm new to PyCharm, and I'm trying to use it for Django development. My app is structured like this:
bs3app/
├── __init__.py
├── templates
│ └── home.html
├── urls.py
└── views.py
In bs3app/views.py, I get a warning:
Template file 'home.html' not found
The source code:
from django.shortcuts import render_to_response
def home(request):
return render_to_response('home.html')
The template file is there in bs3app/templates/home.html. The home view works correctly when I run the site. On the Django Support page of the project, Enable Django Support is on, and the Django project root, Settings and Manage script values are all correct.
So, why am I getting the warning? As per this PyCharm doc page, I can mark the template directories explicitly and then the warning goes away, but why do I have to? Why can't PyCharm figure them out automatically, given the settings.py file of the project?
The project is on GitHub, if you need to see other files.
Just open the project view (view->tool windows -> project). There right-click on your templates-folder -> 'mark directory as'-> Template directory
Try adding TEMPLATE_LOADERS to your settings file if you don't have it. I think PyCharm looks for it and doesn't load it from Django default settings. It solved my problem.
settings.py:
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
If you have marked directory as template directory, but still get the warning, you can try changing the single quotes to double quotes
def home(request):
return render_to_response('home.html')
change to this:
def home(request):
return render_to_response("home.html")
Hope this helps.
I am using PyCharm 2018.2. You can follow the next steps to mark a directory as a template directory, so PyCharm will not give you warnings, and you will be able to go to the template by pressing cmd + B (Mac) or ctrl + B (Windows/Linux):
Open the Settings dialog, and click the Project Structure page. You can use cmd + , (on macOS), or by choosing File | Settings (Windows/Linux)
Choose the directory to be marked as a template root.
Click on Templates on Mark as. In Mac you can also press alt+T.
Click on OK to apply the changes you made.
I had a similar issue that was cause by forgetting to include my app in settings.INSTALLED_APPS. Adding my app to the list cleared the inspection.
It's fixed when I assigned "Django project root" from settings to project destination.
Related
This question was answered more or less here but it didn't work to me and as far I can see more people have the same problem.
In my settings.py I have this lines:
#TEMPLATE_DIRS = [os.path.join(BASE_DIR,'..', 'templates'),]
TEMPLATE_DIRS = ("/root/GODJANGO/thedjango/django_project",)
The comented line didn't work. It works if I write the full path but It's not professional and I don't wanna have problems when I three months later I migrate my server because I will not remember this thing.
Can anybody tell me how to write My Path correctly ("dynamically, I mean")
Please tell me where is the best directory to put my templates folder and also my admin templates folder
If you have the following project layout:
manage.py
myproject/
settings.py
urls.py
wsgi.py
templates/
admin/
app1/
app2/
Then you can dynamically set your template directory by putting the following in your settings.py:
...
SETTINGS_PATH = os.path.abspath(os.path.dirname(__file__))
TEMPLATE_DIRS = (
os.path.join(SETTINGS_PATH, "templates")
)
...
if your template folder is in the parent folder to the settings.py you will need something like:
...
SETTINGS_PATH = os.path.abspath(os.path.dirname(__file__))
PROJECT_FOLDER = (os.path.split(SETTINGS_PATH))[0] # get the parent directory
TEMPLATE_DIRS = (
os.path.join(PROJECT_FOLDER, "templates")
)
...
As you can see, we are manually traversing the file tree to find where the templates folder is and assigning it dynamically.
The best place for your templates folder depends on your project layout (< 1.4 or >= 1.4) but it would be probably safest to say that it should be alongside your settings.py file. Your admin template folder will go inside your base templates folder: templates/admin/.
What are you trying to do with this paramater ".." in the commented line?
if it is means parent directory you can use os.path.dirname(BASE_DIR)
Second part:
It depends you or team work with; i love to keep templates directory in every app's directory (and if you do like this you don't need to define TEMPLATE_DIRS). I mean if i have templates of news app, they goes ../news/templates/. But this time my friend (front-end developer) says i cant find them, can we put all of them in one place?
so i put them in one directory with sub directories (../templates/news/). This main templates directory is in main project directory (near the manage.py file). And if you add this main directory to INSTALLED_APPS (because its kind an app) you don't need to define TEMPLATE_DIRS too. And even you can create models.py admin.py files here.
Considering the second part of your question and according to this the safest part for your templates is to create a templates dir under your projects main directory (e.g. blog).
As for the first part i am not sure.
Is there an easy way to rename a project? I tried to rename the folder, but it didn't work.
Renaming the project is actually easier than renaming an app. This question explains how to rename an app.
To rename the project, you need to change the project name wherever it appears. grep -nir oldname . can help you find where it appears. In my case, I had to change the following places:
Rename the oldprojectname directory to newprojectname
manage.py: Change os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'oldprojectname.settings')
newprojectname/wsgi.py: Change os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'oldprojectname.settings')
newprojectname/settings.py: Change ROOT_URLCONF = 'oldprojectname.urls' and change WSGI_APPLICATION = 'oldprojectname.wsgi.application'
newprojectname/urls.py: Change oldprojectname in a line I had added
very simple and efficient
add this command to any app in your project like this ,
# app/management/commands/renameproject.py
import os
import glob
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
class Command(BaseCommand):
help = 'Renames the Project'
def add_arguments(self, parser):
parser.add_argument('old', nargs='+', type=str, help="current project name")
parser.add_argument('new', nargs='+', type=str, help="new project name")
def handle(self, *args, **options):
old = options["old"][0]
new = options["new"][0]
base = str(settings.BASE_DIR)
projectfiles = []
managefile = os.path.join(base, "manage.py")
projectfiles.append(managefile)
projectfiles += glob.glob(os.path.join(base, old, "*.py"))
projectfiles += glob.glob(os.path.join(base, old, "**", "*.py"))
for pythonfile in projectfiles:
with open(pythonfile, 'r') as file:
filedata = file.read()
filedata = filedata.replace(old, new)
with open(pythonfile, 'w') as file:
file.write(filedata)
os.rename(os.path.join(base, old), os.path.join(base, new))
Now just run this command
python manage.py renameproject oldname newname
have fun 😎
How it works:
Searches .py files across the project and replaces the old name with
new.
To rename a Django project, you need to change the project name wherever it appears.
First of all, rename both outer and inner project directory name from old_project_name to new_project_name
So if the project directory looks like this :
old_project_name // outer project directory old name
old_project_name// inner project directory old name
--__init__.py
--asgi.py
--settings.py
--urls.py
--wsgi.py
app_name // any app u created in the project
db.sqlite3
manage.py
then change to this :
new_project_name // outer project directory new name
new_project_name// inner project directory new name
--__init__.py
--asgi.py
--settings.py
--urls.py
--wsgi.py
app_name // any app u created in the project
db.sqlite3
manage.py
In 2021 with Django version 3.2.3, there are in total 9 places (including comments and codes both) in 5 files where the name of the project appears, which are :
In new_project_name/asgi.py file (comment) :
ASGI config for old_project_name project.
In new_project_name/asgi.py file (code) :
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'old_project_name.settings')
In manage.py file (code) :
os.environ.setdefault('DJANGO_SETTINGS_MODULE', old_project_name.settings')
In new_project_name/settings.py file (comment) :
Django settings for old_project_name project.
In new_project_name/settings.py file (code) :
ROOT_URLCONF = 'old_project_name.urls'
In new_project_name/settings.py (code) :
WSGI_APPLICATION = 'old_project_name.wsgi.application'
In new_project_name/urls.py file (comment) :
old_project_name URL Configuration
In new_project_name/wsgi.py file (comment) :
WSGI config for old_project_name project.
In new_project_name/wsgi.py file (code) :
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'old_project_name.settings')
Note : To change the old_project_name to new_project_name in the files you can use your IDE 's/ text editor's find & replace function to avoid any errors.
Tip : If you haven't done much work in the project then its better to create a new Django project and then just copy and paste the code which don't need any changes rather than changing project name.
I think the best solution here is to simply open your settings.py, urls.py, views.py and any other file that might rely on your project's name and then use the find&replace function in your text editor.
Or, if you haven't done much work yet, start a new project with django-admin.py and copy/paste.
As a beginner with Python and Django, the below simple steps worked for me.
Update both outer and inner folder names in your project (directly from windows explorer or from any editor like visual studio)
Search and replace your old project name with new one in below project files
a. manage.py
b. settings.py
c. wsgi.py
d.asgi.py
e. urls.py
Restart server and confirm if everything works fine again
Actually what you have to do is this:
Open your project in any code editor like Sublime or VSCode
Search for your current project name
In the replace box enter the new project folder name that you want.
Now the code editor will automatically search in the whole project folder and will replace the current project name with the new name.
Now just rename the main app name which is in your project folder
You can now rename your project folder name
Thats it. Hope that helps :)
Suppose your project name is old_project_name and you want to change it to new_project_name. Also you have created an app called my_app within old_project_name. Your directory structure will be something like -
old_project_name
--old_project_name
--__init__.py
--settings.py
--urls.py
--wsgi.py
my_app
--Files and folders under my_app
db.sqlite3
manage.py
Rename both inner and outer old_project_name directory name to new_project_name. After changing your directory structure will be as something like -
new_project_name
--new_project_name
--__init__.py
--settings.py
--urls.py
--wsgi.py
my_app
--Files and folders under my_app
db.sqlite3
manage.py
Change reference to old_project_name in your project files to new_project_name. Mostly you will need to change the reference in settings.py, wsgi.py and manage.py
After these changes run local server and check if your routes are working fine.
Change git repository name. This is optional, but it is advisable as it will be easy to track your projects. If you have added your project to bitbucket or github, then login into bitbucket or github and change the repository name to new_project_name. Suppose your old repository url is https://<yourusername>#bitbucket.org/<yourusername>/old_project_name.git
After renaming repository, your project git url will be changed to something like https://<yourusername>#bitbucket.org/<yourusername>/new_project_name.git>
Run in terminal
git remote -v
it will list your current remote repository url
origin https://<yourusername>#bitbucket.org/<yourusername>/old_project_name.git(fetch)
origin https://<yourusername>#bitbucket.org/<yourusername>/old_project_name.git(push)
Run following command in terminal. This will change your current remote repository url
git remote set-url origin https://<yourusername>#bitbucket.org/<yourusername>/new_project_name.git
Run in terminal
git remote -v
It will now list something like
origin https://<yourusername>#bitbucket.org/<yourusername>/new_project_name.git(fetch)
origin https://<yourusername>#bitbucket.org/<yourusername>/new_project_name.git(push)
Now you can push your new updates to your remote repository.
Update virtual environment. This is optional,but it will help to identify virtual environ mapping to project. I use virtualenvwrapper. If you are using a different one, you will have to update the commands as per your virtual environment.
Run following command in terminal. This will create a copy of old_project_name environment setting with name new_project_name.
cpvirtualenv old_project_name new_project_name
Remove old environment. This step is optional as well.
Run following command in terminal
rmvirtualenv old_project_name
The template file is saved under the app directory, but it raises TemplateDoesNotExist exception while rendering:
Template-loader postmortem as following:
Django tried loading these templates, in this order:
Using loader django.template.loaders.app_directories.Loader:
...
$PROJECT/apps/myapp/templates/search.html (File does not exist)
...
I'm wondering why it looks for:
$PROJECT/apps/myapp/templates/search.html
rather than:
$PROJECT/apps/myapp/templates/myapp/search.html
The latter does exist indeed
$PROJECT/apps/myapp/templates/search.html. That is the path it'll look for as the doc says.
django.template.loaders.app_directories.Loader will look for a templates directory inside all the INSTALLED_APPS in order.
django.template.loaders.filesystem.load_template_source: This loader loads templates from the filesystem, according to TEMPLATE_DIRS. It is enabled by default.
django.template.loaders.app_directories.load_template_source: This loader loads templates from Django applications on the filesystem. For each application in INSTALLED_APPS, the loader looks for a templates subdirectory. If the directory exists, Django looks for templates there.
This means you can store templates with your individual applications, making it easy to distribute Django applications with default templates. For example, if INSTALLED_APPS contains ('myproject.polls', 'myproject.music'), then get_template('foo.html') will look for templates in this order:
/path/to/myproject/polls/templates/foo.html
/path/to/myproject/music/templates/foo.html
Note that the loader performs an optimization when it is first imported: it caches a list of which INSTALLED_APPS packages have a templates subdirectory.
This loader is enabled by default.
Supposing that you have a default project and app created as
django-admin startproject xyz
django-admin startapp abc
both xyz and abc folders are in main project folder
Following minimal changes are required to get first template working
in settings.py change INSTALLED_APPS to add 'abc' (I forgot and failed)
in urls.py add
add line: import abc.views
change urlpatterns to add path('abc/', abc.views.index)
in index definition of views.py use loader.get_template('abc/index.html')
Create abc/templates/abc/index.html file ( I wrote "template" and spent few hours before I realized that is was "templates")
make sure the templates and inside folders have execute permission and html file have read permission for "other" users. (I worked as root and failed due to this error)
Restart the project (runserver or apache2 service)
Summary of my mistakes
Edit INSTALLED_APPS
"templates" is default
setup x and r permissions
Ensure your app is added to settings.py INSTALLED_APPS
Ensure your config in apps.py has a name equal to the name of the application directory.
class DemoConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'app' # this must be the same as the parent directory
Add them to your settings file.
import os
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
TEMPLATE_DIRS = (
os.path.join(PROJECT_ROOT, "/apps/myapp/templates/"),
)
I have a pycharm project and, presumably, a Django project. Perhaps they are one and the same, perhaps not - I'm unsure as to the distinction.
Anyway, in my settings.py file (which is in the root of project directory, which is what I presume is my pycharm project) I have:
ROOT_URLCONF = 'dumpstown.urls'
Does that mean dumpstown is my project name? Or my pycharm project name? What is the distinction? Because I also have a folder called dumpstownapp and this has all my models.py and view.py files. I would have thought that dumpstownapp was the Django project, but I really don't know!
So, to be concise:
In this folder setup
folderA
folderB
views.py
models.py
<other stuff>
templates folder
settings.py
<other stuff>
which is the "Django project name" ~ and by that I mean, if I have a UserProfile defined in my models.py (shown above) what would be the AUTH_PROFILE_MODULE entry I'd need for it? I'm getting several understandings from the django docs - I'd assume
dumpstownapp.models.UserProfile
But from the docs I'd get
dumpstownapp.UserProfile
Or maybe my app is called dumpstown? and then what do I get?
FolderA is the Django project folder, and folderB is the Django app folder.
I haven't used a UserProfile, but according to the docs ( https://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users) it should contain a string containing the Django app name and the model name separated by a dot, so "dumpstownapp.UserProfile" should be correct. If you show the error someone can probably give you better help..
Django documentation used to say that the parent of the project folder (i.e. the parent of folderA) should be on the path, but I believe that has been changed to also include the project folder itself (i.e. folderA) -- since it makes sharing of Django apps much easier. PyCharm seems to assume that is the case, since pressing Alt+F7 to auto-add an import for a newly used module create an import statement that assumes folderA is on the import path (I'm a relative newcomer to PyCharm, and I'm using it on a project that started in the Django 0.96 era, so I might just have things set up wrong..) But folderA is both the Django and the PyCharm project (the .idea file is where PyCharm stores its project data).
In one of my django-app git-submodule projects I needed to find out the name of the Django project that django-app/library was used in. To that end, I tried to get the path of the file that was being executed, find my package in the path and take the folder above it. However, it turned out that on the production server the project was deployed in a folder with a different name (a standard name like www or something along those lines). So this way is not fully reliable.
So I ended up setting a PROJECT variable in the django settings file and using that instead.
I was trying to use a template but it keeps giving me a TemplateDoesNotExist exception. If I look at the Template-loader postmortem, I notice that it is looking in the wrong directory. It is trying to find templates within my workspace folder and not within the location of the project (outside workspace)
If I try to specify a path in settings, it just appends that path to the workspace path.
I'm quite new to Eclipse and PyDev -- how can I sort this out?
I'm using Eclipse 3.7.2 with PyDev 2.4.0 and Django 1.4
This is what I do:
At the top of your file, write these two lines:
import os
ROOT_PATH = os.path.dirname(__file__)
Change TEMPLATE_DIRS to be:
os.path.join(ROOT_PATH, 'templates'),
The 'templates' part should be the relative path to your settings file. In my case it is just templates.
You can also use ROOT_PATH anywhere in the settings, along with join, and it's not a bad idea to use it, because this way your settings file is more universal then constrained to the same machine.
In your settings.py file, there should be a TEMPLATE_DIRS directive. This is a tuple which allows you to set up multiple directories (see below) or just a single entry, as is usually the case. Set that to the appropriate folder and it should work. If that doesn't check permissions on the folder to ensure the runtime user has access to it and the templates.
TEMPLATE_DIRS = (
'/var/www/templates/',
'/opt/myweb/django/templates',
)