What could cause a Django webpage rendering on main domain but not subdomain and localhost?

I’m trying to solve an issue with djangoproject.com. The footer on the bottom right has a “Corporate Membership” link under “Support Us”. The “Corporate Membership” link works when the url is https://www.djangoproject.com/foundation/corporate-membership/%E2%80%9D but not in case of https://docs.djangoproject.com/foundation/corporate-membership/%E2%80%9D or https://dashboard.djangoproject.com/foundation/corporate-membership/%E2%80%9D. It also raises a Page not Found (404) error on the development server, like so

enter image description here

I searched the repo and couldn't find any template for this link, if the template doesn't exist how is it rendering in production?

urls/www.py

from django.conf import settings
from django.contrib import admin
from django.contrib.auth import views as auth_views
from django.contrib.contenttypes import views as contenttypes_views
from django.contrib.flatpages.sitemaps import FlatPageSitemap
from django.contrib.sitemaps import views as sitemap_views
from django.urls import include, path, re_path
from django.views.decorators.cache import cache_page
from django.views.generic import RedirectView, TemplateView
from django.views.static import serve

from accounts import views as account_views
from aggregator.feeds import CommunityAggregatorFeed, CommunityAggregatorFirehoseFeed
from blog.feeds import WeblogEntryFeed
from blog.sitemaps import WeblogSitemap
from foundation.feeds import FoundationMinutesFeed
from foundation.views import CoreDevelopers

admin.autodiscover()

sitemaps = {
    "weblog": WeblogSitemap,
    "flatpages": FlatPageSitemap,
}


urlpatterns = [
    path("", TemplateView.as_view(template_name="homepage.html"), name="homepage"),
    path(
        "start/overview/",
        TemplateView.as_view(template_name="overview.html"),
        name="overview",
    ),
    path("start/", TemplateView.as_view(template_name="start.html"), name="start"),
    # to work around a permanent redirect stored in the db that existed
    #  before the redesign:
    path("overview/", RedirectView.as_view(url="/start/overview/", permanent=False)),
    path("accounts/", include("accounts.urls")),
    # Admin password reset
    path(
        "admin/password_reset/",
        auth_views.PasswordResetView.as_view(),
        name="admin_password_reset",
    ),
    path(
        "admin/password_reset/done/",
        auth_views.PasswordResetDoneView.as_view(),
        name="password_reset_done",
    ),
    path(
        "reset/<uidb64>/<token>/",
        auth_views.PasswordResetConfirmView.as_view(),
        name="password_reset_confirm",
    ),
    path(
        "reset/done/",
        auth_views.PasswordResetCompleteView.as_view(),
        name="password_reset_complete",
    ),
    path("admin/", admin.site.urls),
    path("community/", include("aggregator.urls")),
    path(
        "conduct/",
        TemplateView.as_view(template_name="conduct/index.html"),
        name="code_of_conduct",
    ),
    path(
        "conduct/faq/",
        TemplateView.as_view(template_name="conduct/faq.html"),
        name="conduct_faq",
    ),
    path(
        "conduct/reporting/",
        TemplateView.as_view(template_name="conduct/reporting.html"),
        name="conduct_reporting",
    ),
    path(
        "conduct/enforcement-manual/",
        TemplateView.as_view(template_name="conduct/enforcement.html"),
        name="conduct_enforcement",
    ),
    path(
        "conduct/changes/",
        TemplateView.as_view(template_name="conduct/changes.html"),
        name="conduct_changes",
    ),
    path(
        "diversity/",
        TemplateView.as_view(template_name="diversity/index.html"),
        name="diversity",
    ),
    path(
        "diversity/changes/",
        TemplateView.as_view(template_name="diversity/changes.html"),
        name="diversity_changes",
    ),
    path("contact/", include("contact.urls")),
    path("foundation/django_core/", CoreDevelopers.as_view()),
    path("foundation/minutes/", include("foundation.urls.meetings")),
    path("foundation/", include("members.urls")),
    path("fundraising/", include("fundraising.urls")),
    # Used by docs search suggestions
    re_path(
        r"^r/(?P<content_type_id>\d+)/(?P<object_id>.*)/$",
        contenttypes_views.shortcut,
        name="contenttypes-shortcut",
    ),
    # User stats
    path("~<username>/", account_views.user_profile, name="user_profile"),
    # Feeds
    path("rss/weblog/", WeblogEntryFeed(), name="weblog-feed"),
    path("rss/community/", RedirectView.as_view(url="/rss/community/blogs/")),
    path(
        "rss/community/firehose/",
        CommunityAggregatorFirehoseFeed(),
        name="aggregator-firehose-feed",
    ),
    path("rss/community/<slug>/", CommunityAggregatorFeed(), name="aggregator-feed"),
    path(
        "rss/foundation/minutes/",
        FoundationMinutesFeed(),
        name="foundation-minutes-feed",
    ),
    # django-push
    path("subscriber/", include("django_push.subscriber.urls")),
    # Trac schtuff
    path("trac/", include("tracdb.urls")),
    # Styleguide
    path(
        "styleguide/",
        TemplateView.as_view(template_name="styleguide.html"),
        name="styleguide",
    ),
    path(
        "sitemap.xml",
        cache_page(60 * 60 * 6)(sitemap_views.sitemap),
        {"sitemaps": sitemaps},
    ),
    path("weblog/", include("blog.urls")),
    path("download/", include("releases.urls")),
    path("svntogit/", include("svntogit.urls")),
    path("", include("legacy.urls")),
]

if settings.DEBUG:
    urlpatterns += [
        path("m/<path:path>", serve, {"document_root": settings.MEDIA_ROOT}),
    ]
    try:
        import debug_toolbar
    except ImportError:
        pass
    else:
        urlpatterns += [
            path("__debug__/", include(debug_toolbar.urls)),
        ]

members/urls.py

from django.urls import path
from django.views.generic import RedirectView, TemplateView

from members.views import (
    CorporateMemberBadgesView,
    CorporateMemberRenewView,
    CorporateMemberSignUpView,
    IndividualMemberListView,
    TeamsListView,
    corporate_member_list_view,
)

app_name = "members"
urlpatterns = [
    path(
        "developer-members/",
        RedirectView.as_view(pattern_name="members:individual-members"),
        name="developer-members",
    ),
    path(
        "individual-members/",
        IndividualMemberListView.as_view(),
        name="individual-members",
    ),
    path("corporate-members/", corporate_member_list_view, name="corporate-members"),
    path(
        "corporate-membership/join/",
        CorporateMemberSignUpView.as_view(),
        name="corporate-members-join",
    ),
    path(
        "corporate-membership/renew/<token>/",
        CorporateMemberRenewView.as_view(),
        name="corporate-members-renew",
    ),
    path(
        "corporate-membership/join/thanks/",
        TemplateView.as_view(
            template_name="members/corporate_members_join_thanks.html"
        ),
        name="corporate-members-join-thanks",
    ),
    path(
        "corporate-members/badges/",
        CorporateMemberBadgesView.as_view(),
        name="corporate-members-badges",
    ),
    path("teams/", TeamsListView.as_view(), name="teams"),
]

settings/common.py

# Settings for www.djangoproject.com
import json
import os
from pathlib import Path

# Utilities
PROJECT_PACKAGE = Path(__file__).resolve().parent.parent

# The full path to the repository root.
BASE_DIR = PROJECT_PACKAGE.parent

data_dir_key = "DJANGOPROJECT_DATA_DIR"
DATA_DIR = (
    Path(os.environ[data_dir_key]) if data_dir_key in os.environ else BASE_DIR.parent
)

try:
    with DATA_DIR.joinpath("conf", "secrets.json").open() as handle:
        SECRETS = json.load(handle)
except OSError:
    SECRETS = {
        "secret_key": "a",
        "superfeedr_creds": ["any@email.com", "some_string"],
    }


# Django settings

CACHE_MIDDLEWARE_SECONDS = 60 * 5  # 5 minutes

CACHE_MIDDLEWARE_KEY_PREFIX = "django"

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": os.getenv("DJANGO_DB_NAME", "djangoproject"),
        "USER": SECRETS.get("db_user", "djangoproject"),
        "HOST": SECRETS.get("db_host", ""),
        "PASSWORD": SECRETS.get("db_password", ""),
        "PORT": SECRETS.get("db_port", ""),
    },
    "trac": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": os.getenv("TRAC_DB_NAME", "code.djangoproject"),
        "USER": SECRETS.get("trac_db_user", "code.djangoproject"),
        "HOST": SECRETS.get("trac_db_host", ""),
        "PASSWORD": SECRETS.get("trac_db_password", ""),
        "PORT": SECRETS.get("trac_db_port", ""),
    },
}

DATABASE_ROUTERS = ["tracdb.db_router.TracRouter"]

DEFAULT_FROM_EMAIL = "noreply@djangoproject.com"
FUNDRAISING_DEFAULT_FROM_EMAIL = "fundraising@djangoproject.com"

FIXTURE_DIRS = [str(PROJECT_PACKAGE.joinpath("fixtures"))]

INSTALLED_APPS = [
    "accounts",
    "aggregator",
    "blog",
    "contact",
    "dashboard",
    "docs",
    "foundation",
    "legacy",
    "members",
    "releases",
    "svntogit",
    "tracdb",
    "fundraising",
    "django_recaptcha",
    "registration",
    "django_hosts",
    "sorl.thumbnail",
    "djmoney",
    "django.contrib.sites",
    "django.contrib.auth",
    "django.contrib.admin",
    "django.contrib.contenttypes",
    "django.contrib.flatpages",
    "django.contrib.humanize",
    "django.contrib.messages",
    "django.contrib.postgres",
    "django.contrib.redirects",
    "django.contrib.sessions",
    "django.contrib.staticfiles",
    "django.contrib.sitemaps",
    "django_push.subscriber",
    "django_read_only",
    # Temporary fix for Sphinx bug.https://github.com/sphinx-doc/sphinx/issues/13448
    # Can be removed (and code deleted) once fixed.
    "_sphinx_13448_workaround",
]

LANGUAGE_CODE = "en-us"

LOGGING = {
    "version": 1,
    "disable_existing_loggers": True,
    "formatters": {
        "simple": {"format": "[%(name)s] %(levelname)s: %(message)s"},
        "full": {"format": "%(asctime)s [%(name)s] %(levelname)s: %(message)s"},
        "django.server": {
            "()": "django.utils.log.ServerFormatter",
            "format": "[%(server_time)s] %(message)s",
        },
    },
    "filters": {
        "require_debug_false": {
            "()": "django.utils.log.RequireDebugFalse",
        },
    },
    "handlers": {
        "console": {
            "level": "DEBUG",
            "class": "logging.StreamHandler",
            "formatter": "simple",
        },
        "django.server": {
            "level": "INFO",
            "class": "logging.StreamHandler",
            "formatter": "django.server",
        },
    },
    "loggers": {
        "django.request": {
            "handlers": [],
            "level": "ERROR",
            "propagate": False,
        },
        "django.server": {
            "handlers": ["django.server"],
            "level": "INFO",
            "propagate": False,
        },
    },
}

LOGIN_REDIRECT_URL = "edit_profile"

MEDIA_URL = "/m/"

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    "django_hosts.middleware.HostsRequestMiddleware",
    # Put LocaleMiddleware before SessionMiddleware to prevent
    # the former from accessing the session and adding
    # 'Vary: Cookie' to all responses.
    "djangoproject.middleware.ExcludeHostsLocaleMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.contrib.flatpages.middleware.FlatpageFallbackMiddleware",
    "django.contrib.redirects.middleware.RedirectFallbackMiddleware",
    "django_hosts.middleware.HostsResponseMiddleware",
]

ROOT_URLCONF = "djangoproject.urls.www"

SECRET_KEY = str(SECRETS["secret_key"])

SECURE_BROWSER_XSS_FILTER = True

SECURE_CONTENT_TYPE_NOSNIFF = True

SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTOCOL", "https")

SERVER_EMAIL = "root@djangoproject.com"

SESSION_COOKIE_HTTPONLY = True

SILENCED_SYSTEM_CHECKS = [
    "security.W008",  # SSL redirect is handled by nginx
    "security.W009",  # SECRET_KEY is setup through Ansible secrets
]

SITE_ID = 1

STATICFILES_DIRS = [str(PROJECT_PACKAGE.joinpath("static"))]

STATIC_URL = "/s/"

STATICFILES_FINDERS = (
    "django.contrib.staticfiles.finders.FileSystemFinder",
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
)

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [str(PROJECT_PACKAGE.joinpath("templates"))],
        "APP_DIRS": True,
        "OPTIONS": {
            "builtins": [
                "django_hosts.templatetags.hosts_override",
            ],
            "context_processors": [
                "django.contrib.auth.context_processors.auth",
                "django.template.context_processors.debug",
                "django.template.context_processors.i18n",
                "django.template.context_processors.static",
                "django.template.context_processors.media",
                "django.contrib.messages.context_processors.messages",
                "docs.context_processors.docs_version",
                "releases.context_processors.django_version",
                "aggregator.context_processors.community_stats",
                "django.template.context_processors.request",
            ],
        },
    },
]

TIME_ZONE = "America/Chicago"

USE_I18N = True


USE_TZ = False

# django-contact-form / Akismet settings

AKISMET_API_KEY = "c892e4962244"

# django-hosts settings

DEFAULT_HOST = "www"

HOST_SCHEME = "http"

HOST_SITE_TIMEOUT = 3600

ROOT_HOSTCONF = "djangoproject.hosts"

# django-registration settings

ACCOUNT_ACTIVATION_DAYS = 3

REGISTRATION_EMAIL_HTML = False

# aggregator / PubSubHubbub settings

FEED_APPROVERS_GROUP_NAME = "feed-approver"

# django-push settings

PUSH_HUB = "https://push.superfeedr.com/"

PUSH_CREDENTIALS = "aggregator.utils.push_credentials"

# django-money settings

CURRENCIES = ("USD",)

# SUPERFEEDR_CREDS is a 2 element list in the form of [email,secretkey]
SUPERFEEDR_CREDS = SECRETS.get("superfeedr_creds")

# Fastly credentials
FASTLY_API_KEY = SECRETS.get("fastly_api_key")
FASTLY_SERVICE_URL = SECRETS.get("fastly_service_url")

# Stripe settings

# only testing keys as fallback values here please!
STRIPE_SECRET_KEY = SECRETS.get("stripe_secret_key", "sk_test_x6zP4wd7Z5jcvDOJbbHZlHHt")
STRIPE_PUBLISHABLE_KEY = SECRETS.get(
    "stripe_publishable_key", "pk_test_TyB5jcROwK8mlCNrn3dCwW7l"
)
STRIPE_ENDPOINT_SECRET = SECRETS.get("stripe_endpoint_secret", "insecure")

# product IDs
PRODUCTS = {
    "monthly": {
        "product_id": SECRETS.get("stripe_product_id_monthly", "dummy_monthly_id"),
        "interval": "month",
        "interval_count": 1,
    },
    "quarterly": {
        "product_id": SECRETS.get("stripe_product_id_quarterly", "dummy_quarterly_id"),
        "interval": "month",
        "interval_count": 3,
    },
    "yearly": {
        "product_id": SECRETS.get("stripe_product_id_yearly", "dummy_yearly_id"),
        "interval": "year",
        "interval_count": 1,
    },
    "onetime": {
        "product_id": SECRETS.get("stripe_product_id_onetime", "dummy_onetime_id"),
        "recurring": False,
    },
}

# sorl-thumbnail settings
THUMBNAIL_PRESERVE_FORMAT = True
THUMBNAIL_ALTERNATIVE_RESOLUTIONS = [2]

# dashboard settings
TRAC_URL = "https://code.djangoproject.com/"

DEFAULT_AUTO_FIELD = "django.db.models.AutoField"

FORMS_URLFIELD_ASSUME_HTTPS = True

settings/dev.py

from .common import *  # noqa

ALLOWED_HOSTS = [
    "www.djangoproject.localhost",
    "djangoproject.localhost",
    "docs.djangoproject.localhost",
    "dashboard.djangoproject.localhost",
] + SECRETS.get("allowed_hosts", [])

LOCALE_MIDDLEWARE_EXCLUDED_HOSTS = ["docs.djangoproject.localhost"]

DEBUG = True
THUMBNAIL_DEBUG = DEBUG

CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.dummy.DummyCache",
        "LOCATION": "trololololol",
    },
    "docs-pages": {
        "BACKEND": "django.core.cache.backends.dummy.DummyCache",
        "LOCATION": "docs-pages",
    },
}

CSRF_COOKIE_SECURE = False

EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"

MEDIA_ROOT = str(DATA_DIR.joinpath("media_root"))

SESSION_COOKIE_SECURE = False

STATIC_ROOT = str(DATA_DIR.joinpath("static_root"))

# Docs settings
DOCS_BUILD_ROOT = DATA_DIR.joinpath("djangodocs")

# django-hosts settings

PARENT_HOST = "djangoproject.localhost:8000"

# django-push settings

PUSH_SSL_CALLBACK = False

# Enable optional components

if DEBUG:
    try:
        import debug_toolbar  # NOQA
    except ImportError:
        pass
    else:
        INSTALLED_APPS.append("debug_toolbar")
        INTERNAL_IPS = ["127.0.0.1"]
        MIDDLEWARE.insert(
            MIDDLEWARE.index("django.middleware.common.CommonMiddleware") + 1,
            "debug_toolbar.middleware.DebugToolbarMiddleware",
        )
        MIDDLEWARE.insert(
            MIDDLEWARE.index("debug_toolbar.middleware.DebugToolbarMiddleware") + 1,
            "djangoproject.middleware.CORSMiddleware",
        )

SILENCED_SYSTEM_CHECKS = SILENCED_SYSTEM_CHECKS + [
    # Default test keys for development.
    "django_recaptcha.recaptcha_test_key_error"
]

setting/prod.py

from .common import *  # noqa

DOMAIN_NAME = os.getenv("DOMAIN_NAME", "djangoproject.com")

if not os.getenv("DJANGO_DB_NAME"):
    raise ValueError("You must set DJANGO_DB_NAME in deployed environments.")

ALLOWED_HOSTS = [
    f"www.{DOMAIN_NAME}",
    DOMAIN_NAME,
    f"docs.{DOMAIN_NAME}",
    f"dashboard.{DOMAIN_NAME}",
] + SECRETS.get("allowed_hosts", [])

LOCALE_MIDDLEWARE_EXCLUDED_HOSTS = [f"docs.{DOMAIN_NAME}"]

DEBUG = os.getenv("DJANGO_DEBUG", "false").lower() == "true"
THUMBNAIL_DEBUG = DEBUG

CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.redis.RedisCache",
        "LOCATION": SECRETS.get("cache_default_url", "redis://localhost:6379"),
    },
    # We use a separate cache for docs so we can purge it when docs are rebuilt
    "docs-pages": {
        "BACKEND": "django.core.cache.backends.redis.RedisCache",
        "LOCATION": SECRETS.get("cache_docs_url", "redis://localhost:6379/2"),
    },
}

CSRF_COOKIE_SECURE = True

LOGGING["handlers"]["syslog"] = {
    "formatter": "full",
    "level": "DEBUG",
    "class": "logging.handlers.SysLogHandler",
    "address": "/dev/log",
    "facility": "local4",
}
LOGGING["loggers"]["django.request"]["handlers"].append("syslog")

MEDIA_ROOT = str(DATA_DIR.joinpath("media"))

MEDIA_URL = f"https://media.{DOMAIN_NAME}/"

MIDDLEWARE = (
    ["django.middleware.cache.UpdateCacheMiddleware"]
    + MIDDLEWARE
    + ["django.middleware.cache.FetchFromCacheMiddleware"]
)

SESSION_COOKIE_SECURE = True

STORAGES = {
    "default": {
        "BACKEND": "django.core.files.storage.FileSystemStorage",
    },
    "staticfiles": {
        "BACKEND": "django.contrib.staticfiles.storage.ManifestStaticFilesStorage",
    },
}

STATIC_ROOT = str(DATA_DIR.joinpath("static"))

STATIC_URL = f"https://static.{DOMAIN_NAME}/"

# Docs settings
DOCS_BUILD_ROOT = DATA_DIR.joinpath("data", "docbuilds")

# django-hosts settings

HOST_SCHEME = "https"

PARENT_HOST = DOMAIN_NAME

# django-push settings

PUSH_SSL_CALLBACK = True

# Log errors to Sentry instead of email, if available.
if "sentry_dsn" in SECRETS and not DEBUG:
    import sentry_sdk
    from sentry_sdk.integrations.django import DjangoIntegration
    from sentry_sdk.integrations.redis import RedisIntegration

    sentry_sdk.init(
        dsn=SECRETS["sentry_dsn"],
        integrations=[
            DjangoIntegration(transaction_style="function_name"),
            RedisIntegration(),
        ],
        traces_sample_rate=0.1,
        profiles_sample_rate=1.0,
    )

# RECAPTCHA KEYS
# Defaults will trigger 'django_recaptcha.recaptcha_test_key_error' system check
if "recaptcha_public_key" in SECRETS:
    RECAPTCHA_PUBLIC_KEY = SECRETS.get("recaptcha_public_key")
    RECAPTCHA_PRIVATE_KEY = SECRETS.get("recaptcha_private_key")

RECAPTCHA_REQUIRED_SCORE = 0.9

# Release artifacts are uploaded via the admin and are about 10Mb each
# The nginx configuration still restricts the upload size on most pages.
DATA_UPLOAD_MAX_MEMORY_SIZE = 50 * 1024 * 1024  # 50 Mb

footer.html

 <div class="col-support-us">
          <h3>Support Us</h3>
          <ul>
            <li><a href="{% url "fundraising:index" %}">Sponsor Django</a></li>
            <li><a href="/foundation/corporate-membership/">Corporate membership</a></li>
            <li><a href="https://django.threadless.com/" target="_blank">Official merchandise store</a></li>
            <li><a href="/foundation/donate/#benevity-giving">Benevity Workplace Giving Program</a></li>
          </ul>
        </div>
      </div>
Вернуться на верх