Asked 11 months ago by StarEnvoy233
Why Do Persian Slugs Cause Incorrect Relative URLs in Django on cPanel?
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
Asked 11 months ago by StarEnvoy233
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
I'm experiencing an issue in my Django project when using Persian slugs in URLs. On pages with Persian slug URLs such as example.com/سلام-دنیا
, clicking the signUp button incorrectly appends the slug, leading to a URL like example.com/سلام-دنیا/signUp
instead of the expected example.com/signUp
. This issue doesn't occur with English slugs and works fine on my localhost, but it appears on my cPanel host.
Below are the relevant code snippets:
urls.py in the posts app:
PYTHONfrom django import urls from django.urls import path, re_path from . import views urlpatterns = [ path('', views.posts, name='posts'), path('new_post/', views.new_post, name='new_post'), re_path(r'(?P<slug>[^/]+)/?', views.post, name='post') ]
Template snippet:
DJANGO<a class="btn btn-sm btn-outline-secondary" href="{% url "login" %}">عضویت/ورود</a>
View function in views.py in the posts app:
PYTHONimport os from uuid import uuid4 from django.shortcuts import render, redirect from django.contrib import messages from config import settings from posts.forms import CommentForm, PostCreatorFrom from .decorators import user_is_superuser from posts.utils import paginatePosts, searchPosts from .models import Category, Comment, Post from django.core.paginator import Paginator from django.views.decorators.csrf import csrf_exempt from django.http import JsonResponse from pathlib import Path from urllib.parse import unquote from django.views.decorators.http import require_POST from django.utils.text import slugify from django.utils.encoding import uri_to_iri def post(request, slug): slug = uri_to_iri(slug) postObj = Post.objects.get(slug=slug) form = CommentForm() category = postObj.category related_posts = Post.objects.filter(category=category).exclude(slug=slug)[:3] return render(request, 'posts/post.html', {'post': postObj, 'form': form, 'related_posts': related_posts})
Model definition in models.py:
PYTHONclass Post(models.Model): title = models.CharField(max_length=500, verbose_name="عنوان") slug = models.SlugField(unique=True, verbose_name="آدرس", allow_unicode=True, db_collation='utf8_persian_ci')
Any insight on why this behavior differs on my cPanel host and how to fix it would be greatly appreciated.
Comments 0
•Answers 1
•Views 480
Answer by TychoAI Agent • 9 days ago
The issue you're experiencing with Persian slugs in your Django project is related to how URL patterns are being matched and how relative URLs are being processed on your cPanel host versus your localhost.
The main problem is in your URL pattern configuration. The regular expression pattern in your urls.py
is too greedy:
PYTHONre_path(r'(?P<slug>[^/]+)/?', views.post, name='post')
This pattern will match any URL path that doesn't contain a slash, making it a catch-all route. When you're on a page with a Persian slug (e.g., example.com/سلام-دنیا
), the browser treats links like {% url "login" %}
as relative to the current path rather than the site root.
Here are a few approaches to fix this issue:
Add a $
at the end of your regex to ensure it only matches the exact pattern:
PYTHONre_path(r'^(?P<slug>[^/]+)/?$', views.post, name='post')
The ^
ensures it starts at the beginning of the URL path, and the $
ensures it ends there, preventing it from matching partial paths.
Modify your template links to use absolute URLs:
DJANGO<a class="btn btn-sm btn-outline-secondary" href="/{% url 'login' %}">عضویت/ورود</a>
Or better yet:
DJANGO<a class="btn btn-sm btn-outline-secondary" href="{% url 'login' %}">عضویت/ورود</a>
Make sure your APPEND_SLASH
setting is properly configured. By default, it's set to True
, which means Django will append a slash to URLs that don't match any pattern. This could be affecting how your URLs are processed.
PYTHON# In your settings.py APPEND_SLASH = True # This is the default
This setting only works if CommonMiddleware
is installed, so ensure it's in your MIDDLEWARE
setting.
The difference in behavior between your localhost and cPanel host could be due to:
The most likely cause is that your cPanel host is handling URL routing differently, especially with non-ASCII characters in the URL.
Consider reorganizing your URL patterns to put more specific patterns first and catch-all patterns last.
For Persian slugs, ensure your server is properly configured to handle UTF-8 encoding.
Make sure your SESSION_COOKIE_DOMAIN
is correctly set for your production environment if you're experiencing any login issues.
Consider using Django's built-in reverse()
function in your views to generate URLs rather than hardcoding them.
By implementing these changes, particularly making your URL pattern more specific with the $
at the end, you should be able to resolve the issue with Persian slugs in your URLs.
Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?
No comments yet.
No comments yet.