Skip to main content

A Django app that will analyze and report on links in any model that you register with it.

Project description

GitHub Actions PyPI version

A fairly flexible app that will analyze and report on links in any model that you register with it.

https://github.com/DjangoAdminHackers/django-linkcheck/raw/master/linkcheck.jpg

Links can be bare (urls or image and file fields) or embedded in HTML (linkcheck handles the parsing). It’s fairly easy to override methods of the Linkcheck object should you need to do anything more complicated (like generate URLs from slug fields etc).

You should run its management command via cron or similar to check external links regularly to see if their status changes. All links are checked automatically when objects are saved. This is handled by signals.

Minimal requirements

django-linkcheck requires Python 3.8 and Django 3.2.

Basic usage

  1. Install app to somewhere on your Python path (e.g. pip install django-linkcheck).

  2. Add 'linkcheck' to your settings.INSTALLED_APPS.

  3. Add a file named linklists.py to every app (see an example in examples/linklists.py) that either:

    1. has models that contain content (e.g. url/image fields, chunks of markup or anything that gets transformed into a IMG or HREF when displayed

    2. can be the target of a link - i.e. is addressed by a url - in this case make sure it has an instance method named ‘get_absolute_url’

    Hint: You can create a sample config for your model with:

    manage.py linkcheck_suggest_config --model sampleapp.SampleModel > sampleapp/linklists.py
  4. Run ./manage.py migrate.

  5. Add to your root url config:

    path('admin/linkcheck/', include('linkcheck.urls'))
  6. View /admin/linkcheck/ from your browser.

We are aware that this documentation is on the brief side of things so any suggestions for elaboration or clarification would be gratefully accepted.

Management commands

linkcheck_suggest_config

This command goes through all models and checks whether they contain fields that can potentially be checked by linkcheck. If they are not yet registered, a sample config is suggested.

You can also pass the option --model to generate a sample config for the given model.

Settings

LINKCHECK_DISABLE_LISTENERS

A setting to totally disable linkcheck, typically when running tests. See also the context managers below.

LINKCHECK_EXTERNAL_RECHECK_INTERVAL

Default: 10080 (1 week in minutes)

Will not recheck any external link that has been checked more recently than this value.

LINKCHECK_EXTERNAL_REGEX_STRING

Default: r’^https?://’

A string applied as a regex to a URL to determine whether it’s internal or external.

LINKCHECK_MEDIA_PREFIX

Default: ‘/media/’

Currently linkcheck tests whether links to internal static media are correct by wrangling the URL to be a local filesystem path.

It strips MEDIA_PREFIX off the interal link and concatenates the result onto settings.MEDIA_ROOT and tests that using os.path.exists

This ‘works for me’ but it is probably going to break for other people’s setups. Patches welcome.

LINKCHECK_RESULTS_PER_PAGE

Controls pagination.

Pagination is slightly peculiar at the moment due to the way links are grouped by object.

LINKCHECK_MAX_URL_LENGTH

Default: 255

The length of the URL field. Defaults to 255 for compatibility with MySQL (see http://docs.djangoproject.com/en/dev/ref/databases/#notes-on-specific-fields )

LINKCHECK_CONNECTION_ATTEMPT_TIMEOUT

Default: 10

The timeout in seconds for each connection attempts. Sometimes it is useful to limit check time per connection in order to hold at bay the total check time.

SITE_DOMAIN and LINKCHECK_SITE_DOMAINS

Linkcheck tests external and internal using differently. Internal links use the Django test client whereas external links are tested using urllib2.

Testing internal links this as if they were external can cause errors in some circumstances so Linkcheck needs to know which external urls are to be treated as internal.

Linkcheck looks for either of the settings above. It only uses SITE_DOMAIN if LINKCHECK_SITE_DOMAINS isn’t present

SITE_DOMAIN = “mysite.com”

would tell linkchecker to treat the following as internal links:

mysite.com www.mysite.com test.mysite.com

If you instead set LINKCHECK_SITE_DOMAINS to be a list or tuple then you can explicitly list the domains that should be treated as internal.

LINKCHECK_TOLERATE_BROKEN_ANCHOR

Default: True

Whether links with broken hash anchors should be marked as valid. Disable this if you want that links to anchors which are not contained in the link target’s HTML source are marked as invalid.

django-filebrowser integration

If django-filebrowser is present on your path then linkcheck will listen to the post-upload, delete and rename signals and update itself according

Contributing

You can install all requirements of the development setup with the extra dev:

$ python3 -m venv .venv
$ source .venv/bin/activate
$ pip install -e .[dev]
$ django-admin compilemessages --ignore=.venv  # Optionally compile translation file

If you want to make use of the flake8 and isort pre-commit hooks, enable them with:

$ pre-commit install

Running tests

Tests can be run standalone by using the runtests.py script in linkcheck root:

$ python runtests.py

If you want to run linkcheck tests in the context of your project, you should include 'linkcheck.tests.sampleapp' in your INSTALLED_APPS setting.

Linkcheck gives you two context managers to enable or disable listeners in your own tests. For example:

def test_something_without_listeners(self):
    with listeners.disable_listeners():
        # Create/update here without linkcheck intervening.

In the case you defined the LINKCHECK_DISABLE_LISTENERS setting, you can temporarily enable it by:

def test_something_with_listeners(self):
    with listeners.enable_listeners():
        # Create/update here and see linkcheck activated.

Translations

At the moment this app is available in English, German, and French. If you want to contribute translations for LOCALE, run:

django-admin makemessages --locale LOCALE

and edit the corresponding file in linkcheck/locale/LOCALE/LC_MESSAGES/django.po.

Create new release

  1. Bump version in pyproject.toml

  2. Update CHANGELOG

  3. Create release commit: git commit --message "Release vX.Y.Z"

  4. Create git tag: git tag -a "X.Y.Z" -m "Release vX.Y.Z"

  5. Push the commit and tag to the repository: git push && git push --tags

  6. Build the source distribution: python -m build

  7. Publish the package to PyPI: twine upload dist/django-linkcheck-X.Y.Z*

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-linkcheck-2.3.0.tar.gz (45.0 kB view hashes)

Uploaded Source

Built Distribution

django_linkcheck-2.3.0-py3-none-any.whl (53.2 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page