Right now I have a Django project with three apps. In my last app, the index.html loaded by my views.py is the index.html in another app's templates folder. Note this is how it is actually loading it, but not how I intend it load. The index.html in templates where the corresponding views.py is defined is not used. What I am wondering is how I define my settings so that the templates folder for the current application directory is used. This is my settings.py with respect to templates:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
This is the call to index.html
def indexView(request):
form = FriendForm()
friends = Friend.objects.all()
return render(request, "index1.html", {"form": form, "friends": friends})
A good practice is that from the inside of your urls.py from your app, you add :
app_name = 'your_app_name' # Now, you can call this app from the {% url tag %}
And your template structure should contain app directories, and when you want to render to a different template you can use :
return render(request, 'myApp1/index.html')
return render(request, 'myApp2/index.html')
But remember, in your main templates folder, you need to add 2 directories,
templates/myApp1/index.html,
and
templates/myApp2/index.html
And finally, did you added app_name to your apps URLs? And after that try with the first one, or with the full path.
{% url 'myApp1:post_friend' %} or full path {% url 'myApp1/index.html' %}
Related
I'm working on Django model forms. I have created forms.py and added the following:
from django import forms
from .models import Product
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = [
'title',
'description',
'price'
]
And I have rendered this out in my views.py as it follows:
def product_create_view(request):
form = ProductForm(request.POST or None)
if form.is_valid():
form.save()
context = {
'form': form
}
return render(request, "products/product_create.html", context)
and I have added urls.py:
from django.contrib import admin
from django.urls import path
from pages.views import home_view , contact_view, about_view, social_view
from products.views import product_detail_view, product_create_view
urlpatterns = [
path('', home_view, name='home'),
path('contact/', contact_view),
path('admin/', admin.site.urls),
path('about/', about_view),
path('create/', product_create_view),
path('product/', product_detail_view),
path('social/', social_view),
]
I have migrated everything and saved all files, but when I want to go to my create URL, I get this error:
TemplateDoesNotExist at /create/
products/product_create.html
Request Method: GET
Request URL: http://127.0.0.1:8000/create/
Django Version: 3.2.4
Exception Type: TemplateDoesNotExist
Exception Value:
products/product_create.html
Exception Location: C:\Users\Invoker\dev\trydjango\env\lib\site-packages\django\template\loader.py, line 19, in get_template
Python Executable: C:\Users\Invoker\dev\trydjango\env\Scripts\python.exe
Python Version: 3.9.5
Python Path:
['C:\\Users\\Invoker\\dev\\trydjango\\src\\sadra',
'C:\\Program Files\\Python39\\python39.zip',
'C:\\Program Files\\Python39\\DLLs',
'C:\\Program Files\\Python39\\lib',
'C:\\Program Files\\Python39',
'C:\\Users\\Invoker\\dev\\trydjango\\env',
'C:\\Users\\Invoker\\dev\\trydjango\\env\\lib\\site-packages']
Server time: Wed, 23 Jun 2021 08:20:29 +0000
I have created a template as well:
{% extends 'base.html' %}
{% block content %}
<form>
{{ form.as_p }}
<input type='submit' value='Save' />
</form>
{% endblock %}
Templates in settings.py would be like this:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, "templates")],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
I have my templates in a folder called templates in the root directory. In there I have another folder called products which includes detail.html and product_create.html
What should I do?
I'm a little unclear as to your dir structure as you say "another directory", not a sub directory.
Good practice in Django is to nest dirs under a templates dir using the appname, so in our case
project/templates/products/product_create.html
Should do the trick.
You can have the templates folder in the project root, or you can have it in an app dir for dev (since you have set APP_DIRS to True), but you need to keep the same nesting structure.
As it stands, your project is simply not finding the correct template. Your view has the right path, but the template is in the wrong place.
EDIT: Updated now that I've narrowed down the problem to the context processor variable not being available to a template that I'm loading with a custom tag.
I'm using Django 1.11 and this is my first time trying to use a custom context processor.
The problem is that the context variable I'm supposed to be adding from the context processor does not return anything from within a template loaded from a custom tag. I don't receive any errors.
So below {{ testcontext }} should return "IT WORKED!" and does so in my base.html template, but returns nothing in the template loaded with #register.inclusion_tag().
settings.py:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'appname.context_processors.test_context',
],
},
},
]
context_processors.py:
def test_context(request):
return {'testcontext': 'TEST WORKED!'}
tags.py
from django import template
from appname.models import Category
register = template.Library()
#register.inclusion_tag('template.html')
def load_category(selected_slug=None):
return {
'categories': Category.objects.all(),
'selected':selected_slug,
}
views.py:
from django.views.generic import ListView
from appname.models import MyModel
class MyView(ListView):
model = MyModel
urls.py
from django.conf.urls import url
from appname.views import MyView
urlpatterns = [
url(r'^$', MyView.as_view(), name="home"),
]
template.html
{{ testcontext }}
So the problem was in my custom tag not carrying over the context when loading template.html. So the below code fixes it and my variable from the context processor is now working as expected.
tags.py
from django import template
from appname.models import Category
register = template.Library()
#register.inclusion_tag('template.html', takes_context=True)
def load_category(context,selected_slug=None):
return {
'categories': Category.objects.all(),
'selected': selected_slug,
'testcontext': context['testcontext']
}
First of all i'm new to django . and i'm amazing from this cool framework (not in database part and mysql connector)
And When i looking to django admin style folder in css folder ,
i see rtl css , but now i don't know how can i change admin style to rtl .
This is screen shot from my folders
Thank's
Try setting your language code in settings:
LANGUAGE_CODE = 'fa-ir'
for further reading on translating, rtl, changing date format and other localization things read this django doc.
Django looks at the TEMPLATES setting to find order to check for templates to render. As such, you can add rtl.css to the head of the base admin template in order to load the right-to-left css.
In a templates sub-directory of your main project directory, create dir admin and file base.html. Copy the contents of 'django/contrib/admin/templates/base.html' from Django's source to the newly created file.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')], # <- add this line
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
In the template, you'll see {% block extra_head %}{% endblock %}. Insert the stylesheet link here, like this-
{% block extra_head %}
<link rel='stylesheet' href='{% static 'admin/css/rtl.css' %}' />
{% endblock %}
Now rtl.css will be loaded whenever any admin page is loaded.
I am new to Django. I am using Django 1.8.6 with Python 2.7. I am trying to use a base.html template that can be used globaly through out the entire site, where every app and access it. Here is my test site's current structure:
twms
polls
migrations
static
templates
project
migrations
static
templates
project
index.html
tmws
static
templates
tmws
base.html
Here is the code for project/templates/project/index.html
{% extends 'tmws/base.html' %}
{% block content %}
<h1>Projects</h1>
<ul>
{% for project in project_list %}
<li>{{ project.name }}</li>
{% endfor %}
</ul>
end of list
{% endblock %}
This is the error I am receiving:
TemplateDoesNotExist at /project/
tmws/base.html
How do I access tmws/tmws/templates/tmws/base.html from any of my apps?
Any help would be greatly appreciated!
Let me know if any additional information is needed.
EDIT
Here are my template settings from settings.py:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates'), # If i leave both or just comment one one out I still get the same error
'tmws.tmws.templates'
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
I think you might be having a problem with your template directory configuration. In your project´s settings.py try to check if you have a configuration similar to this one:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'your template dir name')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Where 'your template dir name' should be tmws. This will make django search for this directory whenever you try to extend templates in your HTML. You can add as many directories as you want.
I think right now Django must be searching for the template in:
twms/project/templates/project
So maybe if you place your base.html file there Django will be able to find it.
Another suggestion would be to create a general templates directory and place your base.html there since you want it to be used in the entire site. This is just my taste for ordering templates, but it should work either way.
Edit:
Adding the following in settings.py solved the problem. Read comments for more info:
MASTER_BASE_DIR = os.path.dirname(__file__)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(MASTER_BASE_DIR, 'templates'),]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Check the TEMPLATES value in your settings. You can add the DIR option with a directory where you can put all your common templates.
Link: https://docs.djangoproject.com/en/1.9/ref/settings/#templates
You need to add all templates folders to the TEMPLATES settings in settings.py. Django will then treat them as if they're all in the same folder. It seems like you have not added all of them. You want your TEMPLATES to look something like this:
TEMPLATES = [
{
'DIRS': [
'twms.tmws.templates', # Since this is not in an app
],
'APP_DIRS': True, # Automatically include the templates from INSTALLED_APPS
},
]
You set up the directories to search for the templates as follows:
'DIRS': [os.path.join(MASTER_BASE_DIR, 'templates'),]
where it should read instead:
'DIRS': [os.path.join(MASTER_BASE_DIR, 'tmws/templates'),]
Why? because BASE_DIR is defined as follows:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# -> os.path.dirname(os.path.dirname(/your/path/tmws/tmws/settings.py))
# -> /your/path/tmws/
So BASE_DIR points to your top folder, if you then join it with 'templates', it becomes: /your/path/tmws/templates, which doesn't exist. However, with the changed line in the DIRS list, it will become /your/path/tmws/tmws/templates which is the correct one.
Currently created a templates folder inside my project folder.
Then I added the admin folder and the file base_site.html to be able to change the Django admin title:
Home / Django / mysite / templates / admin / base_site.html
However, it doesn't change. My settings.py file below:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Of Avinash Raj's request:
urls.py:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
]
views.py:
from django.shortcuts import render
Since Django 1.7 you do not need to rewrite any templates to change admin title or header but just set site_header, site_title, and index_title in admin.py & then hook them in urls.py. Look here: https://stackoverflow.com/a/24983231/5253807