Skip to main content

The missing XML sitemaps for Django.

PyPI Version Supported Python versions Build Status Documentation Status GPL-2.0-only OR LGPL-2.1-or-later Coverage

Features

At the moment the following XML sitemaps are implemented:

  • qartez.sitemaps.ImagesSitemap: XML images sitemaps according to the specs.

  • qartez.sitemaps.StaticSitemap: Sitemap for service pages. Add named patterns or URLs to the sitemap to have it nicely displayed in a separate service XML sitemap.

  • qartez.sitemaps.RelAlternateHreflangSitemap: Sitemaps: rel=”alternate” hreflang=”x” implementation. Read the specs.

Prerequisites

  • Django: 1.11, 2.0, 2.1, 2.2 and 3.0.

  • Python: 2.7, 3.5, 3.6, 3.7, 3.8

Installation

1. Install

Latest stable version on PyPI:

pip install django-qartez

Latest stable version from GitHub:

pip install https://github.com/barseghyanartur/django-qartez/archive/stable.tar.gz

2. Add qartez to your INSTALLED_APPS

INSTALLED_APPS = (
    # ...
    'django.contrib.sitemaps',
    'qartez',
    # ...
)

Usage and examples

We have an imaginary foo app.

See the example code.

foo/sitemap.py

from django.contrib.sitemaps import Sitemap

from qartez.sitemaps import (
    ImagesSitemap, StaticSitemap, RelAlternateHreflangSitemap
)

from foo.models import FooItem

# ---------------------- XML images sitemap part ---------------------------
# Dictionary to feed to the images sitemap.
foo_item_images_info_dict = {
    # Base queryset to iterate when procuding a site map
    'queryset': FooItem._default_manager.exclude(image=None),
    'image_location_field': 'image_url', # Image location (URL)
    'image_title_field': 'title', # Image title
    # An absolute URL of the page where image is shown
    'location_field': 'get_absolute_url'
}

# XML images sitemap.
foo_item_images_sitemap = {
    'foo_item_images': ImagesSitemap(foo_item_images_info_dict,
                                     priority=0.6),
}

# ---------------------- Static sitemap part ---------------------------
# Sitemap for service pages like welcome and feedback.
foo_static_sitemap = StaticSitemap(priority=0.1, changefreq='never')
foo_static_sitemap.add_named_pattern('foo.welcome')
foo_static_sitemap.add_named_pattern('foo.contact')

# ---------------------- Normal sitemap part ---------------------------
# Normal Foo items sitemap.
class FooItemSitemap(Sitemap):
    changefreq = "weekly"
    priority = 1.0

    def location(self, obj):
       return obj.get_absolute_url()

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

    def items(self):
       return FooItem._default_manager.all()

# ---------------------- Alternate hreflang sitemap part ---------------
# Alternate hreflang sitemap.
class ArticleSitemap(RelAlternateHreflangSitemap):
    # If you want to serve the links on HTTPS.
    protocol = 'https'

    def alternate_hreflangs(self, obj):
       return [('en-us', obj.alternative_object_url),]

    def items(self):
       return FooItem._default_manager.all()

urls.py

from foo.sitemap import foo_item_images_sitemap, foo_static_sitemap
from foo.sitemap import FooItemAlternateHreflangSitemap, FooItemSitemap

sitemaps = {
    'foo-items': FooItemSitemap,
    'foo-items-alternate-hreflang': FooItemAlternateHreflangSitemap,
    'foo-static': foo_static_sitemap
}

urlpatterns = [
    # Sitemaps
    (
        r'^sitemap\.xml$',
        'django.contrib.sitemaps.views.index',
        {'sitemaps': sitemaps},
    ),

    (
        r'^sitemap-foo-images\.xml$',
        'qartez.views.render_images_sitemap',
        {'sitemaps': foo_item_images_sitemap},
    ),
]

Note, that it’s necessary to add the `'template_name': 'qartez/rel_alternate_hreflang_sitemap.xml'` only in case if you are going to use the qartez.RelAlternateHreflangSitemap.

(
    r'^sitemap-(?P<section>.+)\.xml$',
    'django.contrib.sitemaps.views.sitemap',
    {
        'sitemaps': sitemaps,
        'template_name': 'qartez/rel_alternate_hreflang_sitemap.xml'
    }
),

In order to just get a better idea what kind of models and views are given in the example, see the code parts below.

foo/models.py

class FooItem(models.Model):
    title = models.CharField(_("Title"), max_length=100)
    slug = models.SlugField(_("Slug"), unique=True)
    body = models.TextField(_("Body"))
    date_published = models.DateTimeField(
        _("Date published"),
        blank=True,
        null=True,
        auto_now_add=True
    )

    # Image to be used for XML images sitemap.
    image = models.ImageField(
        _("Headline image"),
        blank=True,
        null=True,
        upload_to='foo-images'
    )

    # URL to be used for alternative hreflang attribute.
    alternative_url = models.URLField(
        _("Alternative URL"),
        blank=True,
        null=True
    )

    class Meta:
       verbose_name = _("Foo item")
       verbose_name_plural = _("Foo items")

    def __str__(self):
       return self.title

    def get_absolute_url(self):
       kwargs = {'slug': self.slug}
       return reverse('foo.detail', kwargs=kwargs)

    # Shortcut to full image URL for XML images sitemap.
    def image_url(self):
       return self.image.url if self.image else ''

foo/views.py

# Service welcome page
def welcome(request, template_name='foo/welcome.html'):
    context = {}
    return render_to_response(
        template_name,
        context,
        context_instance=RequestContext(request)
    )

# Service contact page
def contact(request, template_name='foo/contact.html'):
    context = {}
    return render_to_response(template_name, context, \
                              context_instance=RequestContext(request))

foo/urls.py

urlpatterns = patterns('foo.views',
    # ...
    # Contact URL
    url(r'^contact/$', view='contact', name='foo.contact'),
    # ...
    # Welcome URL
    url(r'^welcome/$', view='welcome', name='foo.welcome'),
    # ...
)

License

GPL-2.0-only OR LGPL-2.1-or-later

Support

For any issues contact me at the e-mail given in the Author section.

Author

Artur Barseghyan <artur.barseghyan@gmail.com>

Release files for django-qartez 0.8.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-qartez 0.8.1
File Size Uploaded
django-qartez-0.8.1.tar.gz 12.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-qartez 0.8.1
File Interpreter ABI Platform
django_qartez-0.8.1-py2.py3-none-any.whl Python 2, Python 3 none any Details

Total release size: 42.4 kB

Release files / django-qartez-0.8.1.tar.gz

Download URL django-qartez-0.8.1.tar.gz
Size 12.6 kB
Tags Source
SHA-256 checksum
How to use checksums
093212a0447b1fd583fe79570b5c716abf4b2f9d2c9fcd09bcaadad56dfe6feb
BLAKE2b-256 checksum
How to use checksums
76f60a080f9ad84c534c11af54dc03463f8eead14c3501e483f27f4a0ea6d165
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Python-urllib/3.8

Release files / django_qartez-0.8.1-py2.py3-none-any.whl

Download URL django_qartez-0.8.1-py2.py3-none-any.whl
Size 29.8 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
82c624605e3d7141c436d6fe48de64a669d8dbc560d2994c91003e1768d7cbae
BLAKE2b-256 checksum
How to use checksums
85c85a2dff790f846f623503a728572a8da312a92a4659716bc4b18497829a46
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Python-urllib/3.8

Release history Release notifications | RSS feed

This release

0.8.1 This release

2 release files

0.8

2 release files

0.7.1

2 release files

0.7

2 release files

0.6

1 release file

0.5

1 release file

0.4

1 release file

0.3

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page