Ramverket för webbplatskartor

Django levereras med ett ramverk för generering av sitemap på hög nivå för att skapa sitemap XML-filer.

Översikt

En webbplatskarta är en XML-fil på din webbplats som berättar för sökmotorindexerare hur ofta dina sidor ändras och hur ”viktiga” vissa sidor är i förhållande till andra sidor på din webbplats. Den här informationen hjälper sökmotorer att indexera din webbplats.

Djangos ramverk för webbplatskartor automatiserar skapandet av denna XML-fil genom att låta dig uttrycka denna information i Python-kod.

Det fungerar ungefär som Djangos syndication-ramverk. För att skapa en webbplatskarta, skriv en Sitemap-klass och peka på den i din URLconf.

Installation

Följ dessa steg för att installera appen för webbplatskartor:

  1. Lägg till 'django.contrib.sitemaps' i inställningen INSTALLED_APPS.

  2. Se till att din TEMPLATES-inställning innehåller en DjangoTemplates-backend vars APP_DIRS-alternativ är inställt på True. Det finns där som standard, så du behöver bara ändra detta om du har ändrat den inställningen.

  3. Se till att du har installerat sites-ramverket.

(Obs: Applikationen för webbplatskartan installerar inga databastabeller. Den enda anledningen till att den behöver läggas in i INSTALLED_APPS är så att Loader() mallladdaren kan hitta standardmallarna)

Initialisering

views.sitemap(request, sitemaps, section=None, template_name='sitemap.xml', content_type='application/xml')

För att aktivera generering av webbplatskartor på din Django-webbplats, lägg till den här raden i din URLconf:

from django.contrib.sitemaps.views import sitemap

path(
    "sitemap.xml",
    sitemap,
    {"sitemaps": sitemaps},
    name="django.contrib.sitemaps.views.sitemap",
)

Detta säger till Django att bygga en webbplatskarta när en klient öppnar /sitemap.xml.

Namnet på sitemap-filen är inte viktigt, men platsen är det. Sökmotorer indexerar bara länkar i din sitemap för den aktuella URL-nivån och lägre. Om till exempel sitemap.xml finns i din rotkatalog kan den referera till vilken URL som helst på din webbplats. Men om din webbplatskarta finns i /content/sitemap.xml kan den bara referera till webbadresser som börjar med /content/.

Sitemap-vyn tar ett extra, obligatoriskt argument: {'sitemaps': sitemaps}. sitemaps bör vara en ordbok som mappar en kort sektionsetikett (t.ex. blogg eller nyheter) till dess Sitemap-klass (t.ex. BlogSitemap eller NewsSitemap). Den kan också mappa till en instans av en Sitemap-klass (t.ex. BlogSitemap(some_var)).

klasserna Sitemap

En Sitemap-klass är en Python-klass som representerar ett ”avsnitt” av poster i din webbplatskarta. Till exempel: kan en sitemap-klass representera alla poster i din blogg, medan en annan kan representera alla händelser i din evenemangskalender.

I det enklaste fallet klumpas alla dessa avsnitt ihop i en sitemap.xml, men det är också möjligt att använda ramverket för att generera ett sitemap-index som refererar till enskilda sitemap-filer, en per avsnitt. (Se ”Skapa ett sitemap-index” nedan.)

Sitemap-klasser måste vara underklasser till django.contrib.sitemaps.Sitemap. De kan finnas var som helst i din kodbas.

Ett exempel

Låt oss anta att du har ett bloggsystem, med en Entry-modell, och du vill att din sitemap ska innehålla alla länkar till dina enskilda blogginlägg. Så här kan din sitemap-klass se ut:

from django.contrib.sitemaps import Sitemap
from blog.models import Entry


class BlogSitemap(Sitemap):
    changefreq = "never"
    priority = 0.5

    def items(self):
        return Entry.objects.filter(is_draft=False)

    def lastmod(self, obj):
        return obj.pub_date

Anteckning:

  • changefreq och priority är klassattribut som motsvarar elementen <changefreq> respektive <priority>. De kan göras anropbara som funktioner, som lastmod var i exemplet.

  • items() is a method that returns a sequence or QuerySet of objects. The objects returned will get passed to any callable methods corresponding to a sitemap property (location, lastmod, changefreq, and priority).

  • lastmod bör returnera en datetime.

  • There is no location method in this example, but you can provide it in order to specify the URL for your object. By default, location calls get_absolute_url() on each object and returns the result.

klassreferens för Sitemap

class Sitemap[source]

En Sitemap-klass kan definiera följande metoder/attribut:

items()[source]

Required. A method that returns a sequence or QuerySet of objects. The framework doesn’t care what type of objects they are; all that matters is that these objects get passed to the location, lastmod, changefreq and priority methods.

location[source]

Optionell. Antingen en metod eller ett attribut.

If it’s a method, it should return the absolute path for a given object as returned by items().

If it’s an attribute, its value should be a string representing an absolute path to use for every object returned by items().

I båda fallen betyder ”absolut sökväg” en URL som inte innehåller protokollet eller domänen. Exempel på detta:

  • Bra: '/foo/bar/'

  • Dålig: 'example.com/foo/bar/'

  • Dålig: 'https://example.com/foo/bar/'

If location isn’t provided, the framework will call the get_absolute_url() method on each object as returned by items.

För att ange ett annat protokoll än 'http', använd protocol.

lastmod

Optionell. Antingen en metod eller ett attribut.

If it’s a method, it should take one argument – an object as returned by items() – and return that object’s last-modified date/time as a datetime.

If it’s an attribute, its value should be a datetime representing the last-modified date/time for every object returned by items().

Om alla objekt i en sitemap har en lastmod, kommer sitemap som genereras av views.sitemap() att ha en Last-Modified header som är lika med den senaste lastmod. Du kan aktivera ConditionalGetMiddleware för att få Django att svara på lämpligt sätt på förfrågningar med en If-Modified-Since header som förhindrar att webbplatskartan skickas om den inte har ändrats.

paginator[source]

**Tillval

This property returns a Paginator for items(). If you generate sitemaps in a batch you may want to override this as a cached property in order to avoid multiple items() calls.

changefreq

Optionell. Antingen en metod eller ett attribut.

If it’s a method, it should take one argument – an object as returned by items() – and return that object’s change frequency as a string.

If it’s an attribute, its value should be a string representing the change frequency of every object returned by items().

Möjliga värden för changefreq, oavsett om du använder en metod eller ett attribut, är:

  • 'always'

  • 'hourly'

  • 'daily'

  • 'weekly'

  • 'monthly'

  • 'yearly'

  • ”aldrig

priority

Optionell. Antingen en metod eller ett attribut.

If it’s a method, it should take one argument – an object as returned by items() – and return that object’s priority as either a string or float.

If it’s an attribute, its value should be either a string or float representing the priority of every object returned by items().

Exempel på värden för priority: 0.4, 1.0. Standardprioriteten för en sida är 0.5. Se sitemaps.org documentation för mer information.

protocol

**Tillval

Detta attribut definierar protokollet ('http' eller 'https') för webbadresserna i webbplatskartan. Om det inte anges används det protokoll som webbplatskartan begärdes med. Om webbplatskartan skapas utanför ramen för en begäran är standardvärdet ``’https’’.

limit

**Tillval

Detta attribut definierar det maximala antalet webbadresser som ingår på varje sida i webbplatskartan. Dess värde bör inte överstiga standardvärdet 50000, vilket är den övre gräns som tillåts i Sitemaps-protokollet.

i18n

**Tillval

Ett booleskt attribut som anger om webbadresserna i den här webbplatskartan ska genereras med alla dina LANGUAGES. Standardvärdet är False.

languages

**Tillval

En sekvens av språkkoder som ska användas för att generera alternativa länkar när i18n är aktiverad. Standard är LANGUAGES.

alternates

**Tillval

Ett boolean-attribut. När det används tillsammans med i18n kommer genererade URL:er att ha en lista med alternativa länkar som pekar på andra språkversioner med hjälp av hreflang-attributet. Standardvärdet är False.

x_default

**Tillval

Ett booleanskt attribut. När det är True kommer de alternativa länkar som genereras av alternates` att innehålla en hreflang="x-default" fallback-post med ett värde av LANGUAGE_CODE. Standardvärdet är False.

get_latest_lastmod()[source]

**En metod som returnerar det senaste värdet som returneras av lastmod. Denna funktion används för att lägga till attributet lastmod till Sitemap index context variables.

Som standard returnerar get_latest_lastmod():

  • Om lastmod är ett attribut: lastmod.

  • If lastmod is a method: The latest lastmod returned by calling the method with all items returned by items().

get_languages_for_item(item)[source]

**En metod som returnerar den sekvens av språkkoder som objektet visas för. Som standard returnerar get_languages_for_item() languages.

Genvägar

Ramverket för webbplatskartor tillhandahåller en bekvämlighetsklass för ett vanligt fall:

class GenericSitemap(info_dict, priority=None, changefreq=None, protocol=None)[source]

Klassen django.contrib.sitemaps.GenericSitemap låter dig skapa en webbplatskarta genom att skicka en ordbok till den, som måste innehålla minst en post med namnet queryset. Denna queryset kommer att användas för att generera objekten i webbplatskartan. Den kan också ha en date_field-post som anger ett datumfält för objekt som hämtas från queryset. Detta kommer att användas för attributet lastmod och metoderna get_latest_lastmod() i den genererade webbplatskartan.

Nyckelordsargumenten priority, changefreq och protocol gör det möjligt att ange dessa attribut för alla URL:er.

Exempel

Här är ett exempel på en URLconf som använder GenericSitemap:

from django.contrib.sitemaps import GenericSitemap
from django.contrib.sitemaps.views import sitemap
from django.urls import path
from blog.models import Entry

info_dict = {
    "queryset": Entry.objects.all(),
    "date_field": "pub_date",
}

urlpatterns = [
    # some generic view using info_dict
    # ...
    # the sitemap
    path(
        "sitemap.xml",
        sitemap,
        {"sitemaps": {"blog": GenericSitemap(info_dict, priority=0.6)}},
        name="django.contrib.sitemaps.views.sitemap",
    ),
]

Sitemap för statiska vyer

Ofta vill du att sökmotorns sökrobotar ska indexera vyer som varken är objektdetaljsidor eller flatpages. Lösningen är att uttryckligen lista URL-namn för dessa vyer i items och anropa reverse`() i location-metoden i sitemap. Till exempel:

# sitemaps.py
from django.contrib import sitemaps
from django.urls import reverse


class StaticViewSitemap(sitemaps.Sitemap):
    priority = 0.5
    changefreq = "daily"

    def items(self):
        return ["main", "about", "license"]

    def location(self, item):
        return reverse(item)


# urls.py
from django.contrib.sitemaps.views import sitemap
from django.urls import path

from .sitemaps import StaticViewSitemap
from . import views

sitemaps = {
    "static": StaticViewSitemap,
}

urlpatterns = [
    path("", views.main, name="main"),
    path("about/", views.about, name="about"),
    path("license/", views.license, name="license"),
    # ...
    path(
        "sitemap.xml",
        sitemap,
        {"sitemaps": sitemaps},
        name="django.contrib.sitemaps.views.sitemap",
    ),
]

Skapa ett index över webbplatskartor

views.index(request, sitemaps, template_name='sitemap_index.xml', content_type='application/xml', sitemap_url_name='django.contrib.sitemaps.views.sitemap')

Sitemap-ramverket har också möjlighet att skapa ett sitemap-index som refererar till enskilda sitemap-filer, en för varje avsnitt som definieras i din sitemaps-dictionary. De enda skillnaderna i användning är:

Så här skulle de relevanta URLconf-raderna se ut för exemplet ovan:

from django.contrib.sitemaps import views

urlpatterns = [
    path(
        "sitemap.xml",
        views.index,
        {"sitemaps": sitemaps},
        name="django.contrib.sitemaps.views.index",
    ),
    path(
        "sitemap-<section>.xml",
        views.sitemap,
        {"sitemaps": sitemaps},
        name="django.contrib.sitemaps.views.sitemap",
    ),
]

Detta kommer automatiskt att generera en sitemap.xml-fil som refererar till både sitemap-flatpages.xml och sitemap-blog.xml. Klasserna Sitemap och dict sitemaps ändras inte alls.

If all sitemaps have a lastmod returned by get_latest_lastmod() the sitemap index will have a Last-Modified header equal to the latest lastmod.

Du bör skapa en indexfil om en av dina sitemaps har mer än 50 000 webbadresser. I det här fallet kommer Django automatiskt att paginera webbplatskartan och indexet kommer att återspegla det.

Om du inte använder vaniljvyn för webbplatskartan - till exempel om den är förpackad med en cachningsdekorator - måste du namnge din webbplatskartvy och skicka sitemap_url_name till indexvyn:

from django.contrib.sitemaps import views as sitemaps_views
from django.views.decorators.cache import cache_page

urlpatterns = [
    path(
        "sitemap.xml",
        cache_page(86400)(sitemaps_views.index),
        {"sitemaps": sitemaps, "sitemap_url_name": "sitemaps"},
    ),
    path(
        "sitemap-<section>.xml",
        cache_page(86400)(sitemaps_views.sitemap),
        {"sitemaps": sitemaps},
        name="sitemaps",
    ),
]

Anpassning av mallar

Om du vill använda en annan mall för varje webbplatskarta eller index för webbplatskartor som finns på din webbplats kan du ange det genom att skicka en parameter ”template_name” till vyerna ”sitemap” och ”index” via URLconf:

from django.contrib.sitemaps import views

urlpatterns = [
    path(
        "custom-sitemap.xml",
        views.index,
        {"sitemaps": sitemaps, "template_name": "custom_sitemap.html"},
        name="django.contrib.sitemaps.views.index",
    ),
    path(
        "custom-sitemap-<section>.xml",
        views.sitemap,
        {"sitemaps": sitemaps, "template_name": "custom_sitemap.html"},
        name="django.contrib.sitemaps.views.sitemap",
    ),
]

Dessa vyer returnerar TemplateResponse-instanser som gör att du enkelt kan anpassa svarsdata före rendering. För mer information, se TemplateResponse-dokumentation.

Variabler i sammanhanget

När du anpassar mallarna för vyerna index() och sitemap() kan du förlita dig på följande kontextvariabler.

Index

Variabeln sitemaps är en lista med objekt som innehåller attributen location och lastmod för var och en av sitemaps. Varje URL innehåller följande attribut:

  • plats: Platsen (webbadress och sida) för webbplatskartan.

  • lastmod: Fylls på av metoden get_latest_lastmod() för varje webbplatskarta.

Webbplatskarta

Variabeln urlset är en lista över webbadresser som ska visas i webbplatskartan. Varje URL har attribut som definieras i klassen Sitemap:

  • alternativ

  • ändringsfrekvens

  • objekt

  • lastmod

  • plats

  • prioritet

Attributet alternates är tillgängligt när i18n och alternates är aktiverade. Det är en lista över andra språkversioner, inklusive den valfria x_default fallbacken, för varje URL. Varje alternativ är en ordbok med nycklarna location och lang_code.

The item attribute has been added for each URL to allow more flexible customization of the templates, such as Google news sitemaps. Assuming Sitemap’s items() would return a list of items with publication_data and a tags field something like this would generate a Google News compatible sitemap:

<?xml version="1.0" encoding="UTF-8"?>
<urlset
  xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"
  xmlns:news="https://www.google.com/schemas/sitemap-news/0.9">
{% spaceless %}
{% for url in urlset %}
  <url>
    <loc>{{ url.location }}</loc>
    {% if url.lastmod %}<lastmod>{{ url.lastmod|date:"Y-m-d" }}</lastmod>{% endif %}
    {% if url.changefreq %}<changefreq>{{ url.changefreq }}</changefreq>{% endif %}
    {% if url.priority %}<priority>{{ url.priority }}</priority>{% endif %}
    <news:news>
      {% if url.item.publication_date %}<news:publication_date>{{ url.item.publication_date|date:"Y-m-d" }}</news:publication_date>{% endif %}
      {% if url.item.tags %}<news:keywords>{{ url.item.tags }}</news:keywords>{% endif %}
    </news:news>
   </url>
{% endfor %}
{% endspaceless %}
</urlset>