I have a Django Website that I am trying to internationalize. Until now it looked like this:
Homepage:
www.myhomepage.com
Another page:
www.myhomepage.com/content/cities
Now I am trying to make it like this:
Homepage:
www.myhomepage.com/en
www.myhomepage.com/de
Another page:
www.myhomepage.com/en/content/cities
www.myhomepage.com/de/content/cities
Following this and this, I managed to make the homepage work, so with www.myhomepage.com/en I see the homepage in English and with www.myhomepage.com/de I see it in German.
The problem comes when I want to go to any other page, like www.myhomepage.com/en/content/cities. Then, the page rendered is still the homepage. Before changing any settings to internationalize it www.myhomepage.com/content/cities was showing up properly.
My guess is that the problem is with the view rendering or the url, but I do not manage to make it work.
Note that the view for www.myhomepage.com belongs to one app and the view for content/cities belongs to a different app.
This is the code I have:
settings.py
MIDDLEWARE_CLASSES = [
...
'django.middleware.locale.LocaleMiddleware',
...
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
...
'django.template.context_processors.i18n',
],
},
},
]
from django.utils.translation import ugettext_lazy as _
LANGUAGES = (
('en', _('English')),
('de', _('German')),
)
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
)
LANGUAGE_CODE = 'en-us'
USE_I18N = True
Main app:
urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
urlpatterns += i18n_patterns('',
url(r'^content/', include('content.urls', namespace='content')),
)
views.py
from django.shortcuts import render
def home_view(request):
...
context = {
...
}
#print('request home', request)
return render(request, 'home_template.html', context)
By activating the print statement and loading www.myhomepage.com/en/content/cities, the following is printed in the console: request home: <WSGIRequest: GET '/en/content/cities/'>, even though this view belongs to the home_page.
Content app:
urls.py
from .views import countries_and_cities
urlpatterns = [
...
url(r'^cities/$', countries_and_cities),
...
]
views.py
from django.shortcuts import render
def countries_and_cities(request):
...
context = {
...
}
return render(request, 'cities_template.html', context)
I have also tried what it is suggested in the docs, without success.
urls.py from main app:
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
from content import views as content_views
content_patterns = ([
url(r'^cities/$', content_views.countries_and_cities, name='cities'),
], 'content')
urlpatterns += i18n_patterns('',
url(r'^content/', include(content_patterns, namespace='content')),
)
What am I doing wrong?
I finally found the problem.
There was another url defined as:
urlpatterns += i18n_patterns(
...
url(r'', include('main.urls')),
...
)
This was causing the problem, even if before going for internationalization it was working properly.
I just changed it to:
urlpatterns += i18n_patterns(
...
url(r'^$', include('main.urls')),
...
)
And it is working properly.
Related
I've been hitting a snag with my Django app. Running Python manage.py runserver in my development environment, I get this error:
django.core.excptions.ImproperlyConfigured. The TEMPLATE_DIRS setting must be a list or a tuple. After changing TEMPLATE_DIRS to a tuple in settings.py as this TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'),) I got :
TypeError('Invalid path type: %s' % type(value).__name__)TypeError: Invalid path type: tuple.
I got a similar response when I changed it to a list.
Meanwhile, running Python manage.py runserver outside the development environment I got:
expected str, bytes or os.PathLike object, not tuple on both times I changed TEMPLATE_DIRS to a list and tuple.
I should also add that my template files aren't loading. I get:
Using the URLconf defined in myProject.urls, Django tried these URL
patterns, in this order:
accounts/
admin/
The current path, index/, didn't match any of these
Here is the project tree:
|_______myApp
|______ |______pycache__
| |______migrations
| |________init__
| |______admin
| |______apps
| |______models
| |______tests
| |______urls
| |______views
|______myProject
| |________init__
| |______asgi
| |______settings
| |______urls
| |______wsgi
|______env
|______static
|______templates
|______myApp
|______index.html
|______signup.html
manage.py
myProject/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('accounts/', include('accounts.urls')),
path('admin/', admin.site.urls),
]
myApp/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('signup/', views.signup, name='signup'),
]
views.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('signup/', views.signup, name='signup'),
]
settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates'), ]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [TEMPLATE_DIRS],
'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',
'django.template.context_processors.media',
], }, },]
I don't know how else to fix it.
TEMPLATE_DIRS is already a list, so it makes no sense to wrap that again in the list, you should define the TEMPLATES setting as:
TEMPLATES = [
{
# …,
'DIRS': TEMPLATE_DIRS,
# …
}
]
I'm not able to import my views in the app folder to the URLS of project folder. I've tried every possible methods like 'from . import views' or 'from newapp import views as newapp_views' and 2-3 more alternatives that I searched on the internet. My app name is newapp and project name is newproject. Please help me.
This is my models file:
from django.db import models
class User(models.Model):
first_name=models.CharField(max_length=128)
last_name=models.CharField(max_length=128)
email=models.EmailField(max_length=256, unique=True)
This is my URLS of newapp folder:
from django.conf.urls import url
from django.urls.resolvers import URLPattern
from .models import views
urlpatterns= [url(r'^$', views.users, name='users'),
]
This is my views of newapp folder:
from django.shortcuts import render
from .models import User
def index(request):
return render(request, 'newapp/index.html')
def users(request):
user_list=User.objects.order_by('first_name')
user_dict={'users': user_list}
return render(request, 'newapp/users.html', context=user_dict)
This is my URLS of newproect folder:
from django.contrib import admin
from django.urls import path,include
from newapp import views
urlpatterns = [
path('', views.index, name='index'),
path('users/',views.users, name="users"),
path('admin/', admin.site.urls),
]
This is my settings file:
from pathlib import Path
import os
BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATE_DIR = os.path.join(BASE_DIR, 'templates')
DEBUG = True
ALLOWED_HOSTS = []
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'newapp'
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [TEMPLATE_DIR,],
'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',
],
},
},
]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
You can't import your file like this: from newapp import views.
And from . import views will work only if your urls.py file is in your app folder, while Django by default put it inside your project folder.
If you choose to have separated urls.py files per app (which is a good practice, as your project could grow into many apps), you could do the following:
newapp/urls.py
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('users/',views.users, name="users"),
path('admin/', admin.site.urls)
]
newproject/urls.py
from django.urls import path, include
urlpatterns = [
path('', include('newapp.urls'))
]
This way you just include the app urls in the project url file, and you can use a path to prefix all the app urls (instead of a blank string as above).
I have created an app for the main template of my project (All other templates inherit from this one). The template includes header, footer and an aside in which i can add and delete posts from the admin panel. Now, when rendering all the templates everything (header, footer and the respective {% block content %}) is shown correctly but not the aside because i'm not passing any url to the view managing it.
I'm trying to pass that view to every URL of my project so the aside is always shown.
I just dont get the way of doing it.
Just to clarify: Following the code i'm going to show now the aside is shown in localhost:8000 only. Not in localhost:8000/inicio nor any other url.
Aside views.py
from django.shortcuts import render
from .models import asides
def post_aside(request):
aside_posts = asides.objects.all()
return render(request, "main/main.html", {"aside_posts" : aside_posts})
urls.py of the app with the aside
from django.urls import path
from . import views
urlpatterns = [
path('', views.post_aside, name='main'),
]
urls.py of the project
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('main.urls')),
path('inicio/', include('inicio.urls')),
path('galeria/', include('galeria.urls')),
path('mapa/', include('mapa.urls')),
path('contacto/', include('contacto.urls')),
path('usuarios/', include('usuarios.urls')),
]
urlpatterns+=static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Create context_processor.py in app where your asides model exists.
Then add inside:
from .models import asides
def website_content(request):
context = {
'aside_posts': asides.objects.all(),
}
return context
Then in your settings.py in context_processors list add on the end:
<your_app>.context_processor.website_content
it should look like:
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',
'aside.context_processor.website_content', # HERE PATH TO YOUR CONTEXT PROCESSOR FUNCTION
],
},
},
]
after this use {% for post in aside_posts %} in your template anywhere you want.
I have completed all seven steps of the Writing your first Django app tutorial for 3.0. Everything works great, except the base site URL for 'mysite' at http://127.0.0.1:8000/. At the beginning of the tutorial, it worked, but it stopped working as I progressed/at the end. http://127.0.0.1:8000/admin/ works fine. Can anyone tell me what I'm doing wrong?
Based on how the tutorial is structured, i.e. "add this and that and this and that," etc., that I overwrote something.
Here is the error I'm receiving in my browser:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
polls/
admin/
The empty path didn't match any of these.
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
Here is the error I'm receiving in Terminal:
Not Found: /
[20/Jun/2020 11:01:22] "GET / HTTP/1.1" 404 2027
Here is my polls/urls.py file:
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
path('<int:question_id>/vote/', views.vote, name='vote'),
]
Here is my mysite/urls.py file:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
Here is TEMPLATES in mysite/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',
],
},
},
]
SOLVED/ANSWER added from comments:
Answer from expert Willem Van Onsem
1. Edit mysite/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('', include('polls.urls')), # no /polls/ prefix
path('admin/', admin.site.urls),
]
2. Run python manage.py runserver
Can anyone tell me what I'm doing wrong?
All your paths for the poll app are here prefixed by polls/, since you wrote:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
You thus can visit the IndexView by fetching the http://127.0.0.1:8000/polls/ URI. If you do not want to prefix the urls, you can rewrite the root urls.py to:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('', include('polls.urls')), # no /polls/ prefix
path('admin/', admin.site.urls),
]
Then you can simply visit http://127.0.0.1:8000/.
I am new to Django. Getting this error (TemplateDoesNotExist ) when I refresh the page .
My code looks like this :
Project name : newsHtml
urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', include('news.urls')),
]
I have created another directory called news where files looks like this :
views.py
from django.http import HttpResponse
from django.template import loader
def index(request):
template= loader.get_template('/home/index.html')
return HttpResponse(template.render(request))
# def index(request):
# return HttpResponse("<h1>its working<\h1>")
urls.py
from django.conf.urls import url
from. import views
urlpatterns = [
url(r'^$',views.index,name='index'),
]
when i uncomment the HttpResponse i am getting the output .
But not able to find why template is not working .
my directory structure looks like this :
First directory :
newsHtml->settings.py,urls.py,wsgi.py
Second directory:
news->templates/home/index.html,views.py,urls.py
I am not able to figure out what is missing . I am using Django 1.11.5.
For a start, why not use the Django shortcut.
from django.shortcuts import render
Your index view should look like so:
def index(request):
return render(request, "home/index.html")
I believe it's because you put a / before your home/index.html.
Also make sure this is in your settings:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'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',
],
},
},
]
Furthermore, ensure your application is inside INSTALLED_APPS.