Skip to main content

Django Check SEO

Replacing some features of Yoast or SEMrush for Django & Django-CMS users.

In other words, django-check-seo will tell you if you have problems concerning a broad range of SEO aspects of your pages.

PyPI PyPI - Downloads GitHub last commit


Requirements

Install

  1. Install the module from PyPI:

    python3 -m pip install django-check-seo
    
  2. Add it in your INSTALLED_APPS:

        "django_check_seo",
    
  3. Add this in your urls.py (add it before the cms.urls line if you're using django CMS):

        path("django-check-seo/", include("django_check_seo.urls")),
    
  4. Update your Django Site objet with a working url (website url for prod env, localhost:8000 for your dev environment).

  5. Add testserver to your ALLOWED_HOSTS (django-check-seo uses the Test Framework in order to get content, instead of doing a regular HTTP request).

  6. Add the permission (use_django_check_seo) to the users/groups you want to let access Django Check SEO.

  7. (optional) Configure the settings (see below ).

  8. that's all folks!


Misc

This application may be used with or without django CMS (a "Check SEO" button will appear in the CMS toolbar if you're using django-cms).

If you're not using Django CMS (only Django), here's the link format you need to use in order to access your pages reports (with or without using i18n):

https://example.com/django-check-seo/?page=/slug-of-page-to-check/
https://example.com/en/django-check-seo/?page=/slug-of-page-to-check/

Settings

Keywords handling new in 2.0.0

Keywords are discovered via a configurable function. Set its import path in your settings:

# This is the default if not set: read from html page <meta name="keywords" content="..."> (comma-separated)
DJANGO_CHECK_SEO_KEYWORDS_DISCOVERY_METHOD = "django_check_seo.utils.keywords_discovery.meta_keywords"

To use keywords stored in the database (models Page and Keyword from Django Check SEO), set this instead:

DJANGO_CHECK_SEO_KEYWORDS_DISCOVERY_METHOD = "django_check_seo.utils.keywords_discovery.model_keywords"
# Set/update keywords through Django Check SEO page:
DJANGO_CHECK_SEO_KEYWORDS_EDITABLE = True

For Django CMS projects, you can use identification by CMS page id + language so that changing a page slug does not break the link to its keywords:

DJANGO_CHECK_SEO_KEYWORDS_DISCOVERY_METHOD = "django_check_seo.utils.keywords_discovery.django_cms_model_keywords"
DJANGO_CHECK_SEO_KEYWORDS_EDITABLE = True

This method is hybrid: CMS pages are identified by (cms_page_id, language); apphooks or other non-CMS URLs are still identified by path. On non-translated sites, language can be left empty or set to your single language code.

Django CMS edit and preview URLs: When the URL you pass to Check SEO is a CMS edit or preview URL (e.g. /en/admin/cms/placeholder/object/3/edit/372/), django-check-seo detects it and either fetches the draft content (preview URL, using your session so no extra login) or the published page (by resolving to the public URL via PageContent/Page models). The result page shows whether the analysis is for the draft or the published page. Optional setting: DJANGO_CHECK_SEO_CMS_EDIT_URL_TO_PUBLIC (default True) to enable resolving edit/preview URLs to the public URL when not using draft.

You're free to implement your own solution to handle keywords.

Select main content (exclude header/footer/...)

Since django-check-seo will count things like number of words on the main content and the number of internal links, it is important to only select the main content of the page (an address in the footer is not the main content of your page).

Django-check-seo use a string (named DJANGO_CHECK_SEO_EXCLUDE_CONTENT) of css selectors to exclude unwanted html nodes from the html content:

DJANGO_CHECK_SEO_EXCLUDE_CONTENT = "tag, .class, #id, tag > .child_class"

Example: See this issue's comment for an example.
You can find a reference table of css selectors explained here (on mdn docs).

Basic config

The basic config (used by default) is located in django-check-seo/conf/settings.py and looks like this:

DJANGO_CHECK_SEO_SETTINGS = {
    "content_words_number": [300, 600],
    "internal_links": 1,
    "external_links": 1,
    "meta_title_length": [30, 60],
    "meta_description_length": [50, 160],
    "keywords_in_first_words": 50,
    "max_link_depth": 3,
    "max_url_length": 70,
}

If you need to change something, just define a dict named DJANGO_CHECK_SEO_SETTINGS in your settings.py.

Custom config example:

If you put this in your settings.py file:

DJANGO_CHECK_SEO_SETTINGS = {
    "internal_links": 25,
    "meta_title_length": [15,30],
}

Then this will be the settings used by the application:

DJANGO_CHECK_SEO_SETTINGS = {
    "content_words_number": [300, 600],
    "internal_links": 25,  # 1 if using default settings
    "external_links": 1,
    "meta_title_length": [15,30],  # [30, 60] if using default settings
    "meta_description_length": [50, 160],
    "keywords_in_first_words": 50,
    "max_link_depth": 3,
    "max_url_length": 70,
}

Want to know more ? See the wiki page Config explained.

Templates

The django_check_seo/default.html template have an <aside> block named seo_aside that you can replace if you want, using the extends & {% block seo_aside %} instructions, like this:

{% extends "django_check_seo/default.html" %}

{% block seo_aside %}
    Hi!
{% endblock seo_aside %}

This template will remplace all the About/Documentation & Raw data (content on the <aside> block) by "Hi!".


Want a video?

https://github.com/user-attachments/assets/a12dd23c-548d-4566-b1e8-4f300c80be7c

How the keywords works.

Want a screenshot?

screenshot

Other (older) screenshots and videos are available on the wiki.


Unit tests

They are located in tests folder.

# Create test venv & install dependencies
python3 -m venv .venv && . .venv/bin/activate && python3 -m pip install django bs4 lxml djangocms-page-meta requests pytest pytest-django pytest-cov unidecode "hypothesis[django]"

Launch tests

# Souce venv, launch tests (including coverage & fuzzy testing)
. .venv/bin/activate && python3 -m pytest -s --cov=django_check_seo --cov-report term-missing  # -s --hypothesis-verbosity=verbose  # if you want to see the values tested by hypothesis)

Contributing

See CONTRIBUTING.md.

Release files for django-check-seo 2.1.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-check-seo 2.1.1
File Size Uploaded
django_check_seo-2.1.1.tar.gz 614.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-check-seo 2.1.1
File Interpreter ABI Platform
django_check_seo-2.1.1-py3-none-any.whl Python 3 none any Details

Total release size:1.2 MB

Release files / django_check_seo-2.1.1.tar.gz

Download URL django_check_seo-2.1.1.tar.gz
Size 614.5 kB
Tags Source
SHA-256 checksum
How to use checksums
6c49e724533bbd3baaf8fb01e058057af8bf62842f9bab6ece8cae7648019468
BLAKE2b-256 checksum
How to use checksums
efd5f85b7a9de189f6d6da5c9ba98777c19a7d21e4f8ca2bd29a2475a8614bbe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.3.2 CPython/3.11.2 Linux/6.8.0-101-generic

Release files / django_check_seo-2.1.1-py3-none-any.whl

Download URL django_check_seo-2.1.1-py3-none-any.whl
Size 614.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
87d81729206d8b49041c0780c12c06524484e40aa4c61ec4c4a60a6ce3b4dc16
BLAKE2b-256 checksum
How to use checksums
30288ae95fad22974f433cb47b0d1b0316201b864fb7d6261bd1c4a725eeab9c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.3.2 CPython/3.11.2 Linux/6.8.0-101-generic

Release history Release notifications | RSS feed

This release

2.1.1 This release

2 release files

2.1.0

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.7

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.5.3

2 release files

0.5.2

1 release file

0.5.1

1 release file

0.5.0

1 release file

0.4.3

1 release file

0.4.2

1 release file

0.4.1

1 release file

0.4.0

1 release file

0.3.7

1 release file

0.3.6

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

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