From 4dba03493300f43c12fdfd2368de6bc7b2fd2b40 Mon Sep 17 00:00:00 2001
From: srijanid <srijanidas06@gmail.com>
Date: Fri, 31 Jan 2025 23:17:46 +0530
Subject: [PATCH 1/2] improving 404 page

---
 djangoproject/templates/404.html | 52 ++++++++++++++++++++++++--------
 docs/templatetags/docs.py        | 38 ++++++++++++++++++-----
 2 files changed, 70 insertions(+), 20 deletions(-)

diff --git a/djangoproject/templates/404.html b/djangoproject/templates/404.html
index 885c594a3b..10d2eadecb 100644
--- a/djangoproject/templates/404.html
+++ b/djangoproject/templates/404.html
@@ -1,23 +1,51 @@
 {% extends 'base_error.html' %}
 {% load i18n %}
+{% load custom_tags %}
 
 {% block title %}{% translate "Page not found" %}{% endblock %}
 
-{% block header %}<h1>404</h1>{% endblock %}
+{% block header %}
+  <h1 class="error-title">404 - Page Not Found</h1>
+  <p class="error-subtitle">
+    {% translate "Oops! The page you’re looking for doesn’t exist." %}
+  </p>
+{% endblock %}
 
 {% block content %}
-  <h2>{% translate "Page not found" %}</h2>
+  <div class="error-container">
+    <h2>{% translate "We couldn’t find the page:" %}</h2>
+    <p class="broken-url">"<strong>{{ broken_path }}</strong>"</p>
+
+    <p>
+      {% blocktranslate trimmed %}
+        Looks like you followed a bad link. If you think it's our fault, please
+        <a href="https://code.djangoproject.com/">let us know</a>.
+      {% endblocktranslate %}
+    </p>
 
-  <p>
-    {% blocktranslate trimmed %}
-      Looks like you followed a bad link. If you think it's our fault, please
-      <a href="https://code.djangoproject.com/">let us know</a>.
-    {% endblocktranslate %}</p>
+    <!-- Search Form -->
+    <div class="search-container">
+      <form method="get" action="{% url 'doc_search' %}">
+        {{ form.as_p }}
+        <button type="submit" class="search-button">{% translate "Search Docs" %}</button>
+      </form>
+    </div>
 
-  {% url 'homepage' as homepage_url %}
-  <p>
-    {% blocktranslate trimmed %}
-      Here's a link to the <a href="{{ homepage_url }}">homepage</a>. You know, just in case.
-    {% endblocktranslate %}</p>
+    <!-- Suggested Closest Matches -->
+    {% if suggestions %}
+      <h3>{% translate "Did you mean?" %}</h3>
+      <ul class="suggestion-list">
+        {% for suggestion in suggestions %}
+          <li><a href="{{ suggestion }}">{{ suggestion }}</a></li>
+        {% endfor %}
+      </ul>
+    {% endif %}
 
+    {% url 'homepage' as homepage_url %}
+    <p>
+      {% blocktranslate trimmed %}
+        Here's a link to the <a href="{{ homepage_url }}">homepage</a>. You know, just in case.
+      {% endblocktranslate %}
+    </p>
+  </div>
 {% endblock %}
diff --git a/docs/templatetags/docs.py b/docs/templatetags/docs.py
index 194a77e7f2..7732542dc0 100644
--- a/docs/templatetags/docs.py
+++ b/docs/templatetags/docs.py
@@ -1,28 +1,50 @@
 from django import template
 from django.utils.safestring import mark_safe
-from django.utils.version import get_version_tuple
+from django.utils.version import get_version_tuple # 
 from pygments import highlight
 from pygments.formatters.html import HtmlFormatter
 from pygments.lexers import get_lexer_by_name
-
+import difflib
+from django.shortcuts import get_object_or_404
+from django.urls import reverse
+from django.http import Http404
+from django.conf import settings
 from ..forms import DocSearchForm
 from ..models import DocumentRelease
 from ..utils import get_doc_path, get_doc_root
 
 register = template.Library()
 
+# List of existing docs URLs for similarity matching
+EXISTING_DOCS_URLS = [
+    "/en/4.2/ref/databases/",
+    "/en/4.2/ref/models/",
+    "/en/4.2/topics/db/",
+    "/en/4.2/howto/custom-model-fields/",
+    "/en/4.2/ref/settings/",
+    # Add more known URLs as needed
+]
+
+def get_suggestions(broken_url):
+    """Finds close matches for the broken URL using difflib."""
+    return difflib.get_close_matches(broken_url, EXISTING_DOCS_URLS, n=3, cutoff=0.6)
 
 @register.inclusion_tag("docs/search_form.html", takes_context=True)
 def search_form(context):
     request = context["request"]
-    release = DocumentRelease.objects.get_by_version_and_lang(
-        context["version"],
-        context["lang"],
-    )
+    version = context.get("version", context.get("DJANGO_VERSION"))
+    lang = context.get("lang", context.get("LANGUAGE_CODE"))
+
+    release = get_object_or_404(DocumentRelease, version=version, lang=lang)
+    broken_path = request.path.replace(f"/{lang}/{version}/", "", 1)
+    suggestions = get_suggestions(f"/{broken_path}")
+
     return {
         "form": DocSearchForm(request.GET, release=release),
-        "version": context["version"],
-        "lang": context["lang"],
+        "version": version,
+        "lang": lang,
+        "suggestions": suggestions,
+        "broken_path": broken_path,
     }
 
 

From e64f785503ad9c1725d64ac99e878041d9f4a1b2 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
 <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Fri, 31 Jan 2025 17:53:09 +0000
Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci
---
 docs/templatetags/docs.py | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/docs/templatetags/docs.py b/docs/templatetags/docs.py
index 7732542dc0..cdd5e597ee 100644
--- a/docs/templatetags/docs.py
+++ b/docs/templatetags/docs.py
@@ -1,14 +1,16 @@
+import difflib
+
 from django import template
+from django.conf import settings
+from django.http import Http404
+from django.shortcuts import get_object_or_404
+from django.urls import reverse
 from django.utils.safestring import mark_safe
-from django.utils.version import get_version_tuple # 
+from django.utils.version import get_version_tuple
 from pygments import highlight
 from pygments.formatters.html import HtmlFormatter
 from pygments.lexers import get_lexer_by_name
-import difflib
-from django.shortcuts import get_object_or_404
-from django.urls import reverse
-from django.http import Http404
-from django.conf import settings
+
 from ..forms import DocSearchForm
 from ..models import DocumentRelease
 from ..utils import get_doc_path, get_doc_root
@@ -25,10 +27,12 @@
     # Add more known URLs as needed
 ]
 
+
 def get_suggestions(broken_url):
     """Finds close matches for the broken URL using difflib."""
     return difflib.get_close_matches(broken_url, EXISTING_DOCS_URLS, n=3, cutoff=0.6)
 
+
 @register.inclusion_tag("docs/search_form.html", takes_context=True)
 def search_form(context):
     request = context["request"]