mirror of
https://github.com/django/django.git
synced 2024-12-22 09:05:43 +00:00
Fixed #34688 -- Removed contrib.sitemaps.ping_google() and ping_google management command.
Thanks Joachim Jablon for the report. Google has deprecated the sitemap ping endpoint, and will be removing it in 6 months ~January 2024.
This commit is contained in:
parent
2584783f46
commit
6d427288e4
@ -1,60 +1,9 @@
|
||||
from urllib.parse import urlencode
|
||||
from urllib.request import urlopen
|
||||
|
||||
from django.apps import apps as django_apps
|
||||
from django.conf import settings
|
||||
from django.core import paginator
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.urls import NoReverseMatch, reverse
|
||||
from django.utils import translation
|
||||
|
||||
PING_URL = "https://www.google.com/webmasters/tools/ping"
|
||||
|
||||
|
||||
class SitemapNotFound(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def ping_google(sitemap_url=None, ping_url=PING_URL, sitemap_uses_https=True):
|
||||
"""
|
||||
Alert Google that the sitemap for the current site has been updated.
|
||||
If sitemap_url is provided, it should be an absolute path to the sitemap
|
||||
for this site -- e.g., '/sitemap.xml'. If sitemap_url is not provided, this
|
||||
function will attempt to deduce it by using urls.reverse().
|
||||
"""
|
||||
sitemap_full_url = _get_sitemap_full_url(sitemap_url, sitemap_uses_https)
|
||||
params = urlencode({"sitemap": sitemap_full_url})
|
||||
urlopen("%s?%s" % (ping_url, params))
|
||||
|
||||
|
||||
def _get_sitemap_full_url(sitemap_url, sitemap_uses_https=True):
|
||||
if not django_apps.is_installed("django.contrib.sites"):
|
||||
raise ImproperlyConfigured(
|
||||
"ping_google requires django.contrib.sites, which isn't installed."
|
||||
)
|
||||
|
||||
if sitemap_url is None:
|
||||
try:
|
||||
# First, try to get the "index" sitemap URL.
|
||||
sitemap_url = reverse("django.contrib.sitemaps.views.index")
|
||||
except NoReverseMatch:
|
||||
try:
|
||||
# Next, try for the "global" sitemap URL.
|
||||
sitemap_url = reverse("django.contrib.sitemaps.views.sitemap")
|
||||
except NoReverseMatch:
|
||||
pass
|
||||
|
||||
if sitemap_url is None:
|
||||
raise SitemapNotFound(
|
||||
"You didn't provide a sitemap_url, and the sitemap URL couldn't be "
|
||||
"auto-detected."
|
||||
)
|
||||
|
||||
Site = django_apps.get_model("sites.Site")
|
||||
current_site = Site.objects.get_current()
|
||||
scheme = "https" if sitemap_uses_https else "http"
|
||||
return "%s://%s%s" % (scheme, current_site.domain, sitemap_url)
|
||||
|
||||
|
||||
class Sitemap:
|
||||
# This limit is defined by Google. See the index documentation at
|
||||
|
@ -1,16 +0,0 @@
|
||||
from django.contrib.sitemaps import ping_google
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Ping Google with an updated sitemap, pass optional url of sitemap"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument("sitemap_url", nargs="?")
|
||||
parser.add_argument("--sitemap-uses-http", action="store_true")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
ping_google(
|
||||
sitemap_url=options["sitemap_url"],
|
||||
sitemap_uses_https=not options["sitemap_uses_http"],
|
||||
)
|
@ -588,78 +588,3 @@ generate a Google News compatible sitemap:
|
||||
</urlset>
|
||||
|
||||
.. _`Google news sitemaps`: https://support.google.com/news/publisher-center/answer/9606710
|
||||
|
||||
Pinging Google
|
||||
==============
|
||||
|
||||
You may want to "ping" Google when your sitemap changes, to let it know to
|
||||
reindex your site. The sitemaps framework provides a function to do just
|
||||
that: :func:`django.contrib.sitemaps.ping_google()`.
|
||||
|
||||
.. function:: ping_google(sitemap_url=None, ping_url=PING_URL, sitemap_uses_https=True)
|
||||
|
||||
``ping_google`` takes these optional arguments:
|
||||
|
||||
* ``sitemap_url`` - The absolute path to your site's sitemap (e.g.,
|
||||
:file:`'/sitemap.xml'`).
|
||||
|
||||
If this argument isn't provided, ``ping_google`` will perform a reverse
|
||||
lookup in your URLconf, for URLs named
|
||||
``'django.contrib.sitemaps.views.index'`` and then
|
||||
``'django.contrib.sitemaps.views.sitemap'`` (without further arguments) to
|
||||
automatically determine the sitemap URL.
|
||||
|
||||
* ``ping_url`` - Defaults to Google's Ping Tool:
|
||||
https://www.google.com/webmasters/tools/ping.
|
||||
|
||||
* ``sitemap_uses_https`` - Set to ``False`` if your site uses ``http``
|
||||
rather than ``https``.
|
||||
|
||||
:func:`ping_google` raises the exception
|
||||
``django.contrib.sitemaps.SitemapNotFound`` if it cannot determine your
|
||||
sitemap URL.
|
||||
|
||||
.. admonition:: Register with Google first!
|
||||
|
||||
The :func:`ping_google` command only works if you have registered your
|
||||
site with `Google Search Console`_.
|
||||
|
||||
.. _`Google Search Console`: https://search.google.com/search-console/welcome
|
||||
|
||||
One useful way to call :func:`ping_google` is from a model's ``save()``
|
||||
method::
|
||||
|
||||
from django.contrib.sitemaps import ping_google
|
||||
|
||||
|
||||
class Entry(models.Model):
|
||||
# ...
|
||||
def save(self, force_insert=False, force_update=False):
|
||||
super().save(force_insert, force_update)
|
||||
try:
|
||||
ping_google()
|
||||
except Exception:
|
||||
# Bare 'except' because we could get a variety
|
||||
# of HTTP-related exceptions.
|
||||
pass
|
||||
|
||||
A more efficient solution, however, would be to call :func:`ping_google` from a
|
||||
cron script, or some other scheduled task. The function makes an HTTP request
|
||||
to Google's servers, so you may not want to introduce that network overhead
|
||||
each time you call ``save()``.
|
||||
|
||||
Pinging Google via ``manage.py``
|
||||
--------------------------------
|
||||
|
||||
.. django-admin:: ping_google [sitemap_url]
|
||||
|
||||
Once the sitemaps application is added to your project, you may also
|
||||
ping Google using the ``ping_google`` management command:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
python manage.py ping_google [/sitemap.xml]
|
||||
|
||||
.. django-admin-option:: --sitemap-uses-http
|
||||
|
||||
Use this option if your sitemap uses ``http`` rather than ``https``.
|
||||
|
@ -1759,18 +1759,6 @@ documentation.
|
||||
|
||||
Can be run as a cron job or directly to clean out expired sessions.
|
||||
|
||||
``django.contrib.sitemaps``
|
||||
---------------------------
|
||||
|
||||
``ping_google``
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
This command is only available if the :doc:`Sitemaps framework
|
||||
</ref/contrib/sitemaps>` (``django.contrib.sitemaps``) is installed.
|
||||
|
||||
Please refer to its :djadmin:`description <ping_google>` in the Sitemaps
|
||||
documentation.
|
||||
|
||||
``django.contrib.staticfiles``
|
||||
------------------------------
|
||||
|
||||
|
@ -455,10 +455,10 @@ Miscellaneous
|
||||
passed as a value to encode because ``None`` can't be encoded in GET and POST
|
||||
data. Either pass an empty string or omit the value.
|
||||
|
||||
* The :djadmin:`ping_google` management command now defaults to ``https``
|
||||
* The ``ping_google`` management command now defaults to ``https``
|
||||
instead of ``http`` for the sitemap's URL. If your site uses http, use the
|
||||
new :option:`ping_google --sitemap-uses-http` option. If you use the
|
||||
:func:`~django.contrib.sitemaps.ping_google` function, set the new
|
||||
new ``ping_google --sitemap-uses-http`` option. If you use the
|
||||
``django.contrib.sitemaps.ping_google`` function, set the new
|
||||
``sitemap_uses_https`` argument to ``False``.
|
||||
|
||||
* :djadmin:`runserver` no longer supports ``pyinotify`` (replaced by Watchman).
|
||||
|
@ -443,6 +443,15 @@ backends.
|
||||
|
||||
* Support for GEOS 3.6 and 3.7 is removed.
|
||||
|
||||
:mod:`django.contrib.sitemaps`
|
||||
------------------------------
|
||||
|
||||
* The ``django.contrib.sitemaps.ping_google()`` function and the
|
||||
``ping_google`` management command are removed as the Google
|
||||
Sitemaps ping endpoint is deprecated and will be removed in January 2024.
|
||||
|
||||
* The ``django.contrib.sitemaps.SitemapNotFound`` exception class is removed.
|
||||
|
||||
Using ``create_defaults__exact`` may now be required with ``QuerySet.update_or_create()``
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -1,18 +0,0 @@
|
||||
from unittest import mock
|
||||
|
||||
from django.core.management import call_command
|
||||
|
||||
from .base import SitemapTestsBase
|
||||
|
||||
|
||||
@mock.patch("django.contrib.sitemaps.management.commands.ping_google.ping_google")
|
||||
class PingGoogleTests(SitemapTestsBase):
|
||||
def test_default(self, ping_google_func):
|
||||
call_command("ping_google")
|
||||
ping_google_func.assert_called_with(sitemap_url=None, sitemap_uses_https=True)
|
||||
|
||||
def test_args(self, ping_google_func):
|
||||
call_command("ping_google", "foo.xml", "--sitemap-uses-http")
|
||||
ping_google_func.assert_called_with(
|
||||
sitemap_url="foo.xml", sitemap_uses_https=False
|
||||
)
|
@ -1,59 +0,0 @@
|
||||
from unittest import mock
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from django.contrib.sitemaps import SitemapNotFound, _get_sitemap_full_url, ping_google
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.test import modify_settings, override_settings
|
||||
|
||||
from .base import SitemapTestsBase
|
||||
|
||||
|
||||
class PingGoogleTests(SitemapTestsBase):
|
||||
@override_settings(ROOT_URLCONF="sitemaps_tests.urls.sitemap_only")
|
||||
@mock.patch("django.contrib.sitemaps.urlopen")
|
||||
def test_something(self, urlopen):
|
||||
ping_google()
|
||||
params = urlencode(
|
||||
{"sitemap": "https://example.com/sitemap-without-entries/sitemap.xml"}
|
||||
)
|
||||
full_url = "https://www.google.com/webmasters/tools/ping?%s" % params
|
||||
urlopen.assert_called_with(full_url)
|
||||
|
||||
@override_settings(ROOT_URLCONF="sitemaps_tests.urls.sitemap_only")
|
||||
def test_get_sitemap_full_url_global(self):
|
||||
self.assertEqual(
|
||||
_get_sitemap_full_url(None),
|
||||
"https://example.com/sitemap-without-entries/sitemap.xml",
|
||||
)
|
||||
|
||||
@override_settings(ROOT_URLCONF="sitemaps_tests.urls.index_only")
|
||||
def test_get_sitemap_full_url_index(self):
|
||||
self.assertEqual(
|
||||
_get_sitemap_full_url(None), "https://example.com/simple/index.xml"
|
||||
)
|
||||
|
||||
@override_settings(ROOT_URLCONF="sitemaps_tests.urls.empty")
|
||||
def test_get_sitemap_full_url_not_detected(self):
|
||||
msg = (
|
||||
"You didn't provide a sitemap_url, and the sitemap URL couldn't be "
|
||||
"auto-detected."
|
||||
)
|
||||
with self.assertRaisesMessage(SitemapNotFound, msg):
|
||||
_get_sitemap_full_url(None)
|
||||
|
||||
def test_get_sitemap_full_url_exact_url(self):
|
||||
self.assertEqual(
|
||||
_get_sitemap_full_url("/foo.xml"), "https://example.com/foo.xml"
|
||||
)
|
||||
|
||||
def test_get_sitemap_full_url_insecure(self):
|
||||
self.assertEqual(
|
||||
_get_sitemap_full_url("/foo.xml", sitemap_uses_https=False),
|
||||
"http://example.com/foo.xml",
|
||||
)
|
||||
|
||||
@modify_settings(INSTALLED_APPS={"remove": "django.contrib.sites"})
|
||||
def test_get_sitemap_full_url_no_sites(self):
|
||||
msg = "ping_google requires django.contrib.sites, which isn't installed."
|
||||
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||
_get_sitemap_full_url(None)
|
@ -1 +0,0 @@
|
||||
urlpatterns = []
|
@ -1,13 +0,0 @@
|
||||
from django.contrib.sitemaps import views
|
||||
from django.urls import path
|
||||
|
||||
from .http import simple_sitemaps
|
||||
|
||||
urlpatterns = [
|
||||
path(
|
||||
"simple/index.xml",
|
||||
views.index,
|
||||
{"sitemaps": simple_sitemaps},
|
||||
name="django.contrib.sitemaps.views.index",
|
||||
),
|
||||
]
|
@ -1,11 +0,0 @@
|
||||
from django.contrib.sitemaps import views
|
||||
from django.urls import path
|
||||
|
||||
urlpatterns = [
|
||||
path(
|
||||
"sitemap-without-entries/sitemap.xml",
|
||||
views.sitemap,
|
||||
{"sitemaps": {}},
|
||||
name="django.contrib.sitemaps.views.sitemap",
|
||||
),
|
||||
]
|
Loading…
Reference in New Issue
Block a user