• Stars
    star
    641
  • Rank 70,212 (Top 2 %)
  • Language
    Python
  • License
    MIT License
  • Created about 3 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Automatically upgrade your Django projects.

django-upgrade

https://img.shields.io/github/actions/workflow/status/adamchainz/django-upgrade/main.yml?branch=main&style=for-the-badge https://img.shields.io/badge/Coverage-100%25-success?style=for-the-badge https://img.shields.io/pypi/v/django-upgrade.svg?style=for-the-badge https://img.shields.io/badge/code%20style-black-000000.svg?style=for-the-badge pre-commit

Automatically upgrade your Django project code.

Installation

Use pip:

python -m pip install django-upgrade

Python 3.8 to 3.11 supported.

pre-commit hook

You can also install django-upgrade as a pre-commit hook. Add the following to the repos section of your .pre-commit-config.yaml file (docs), above any code formatters (such as Black):

-   repo: https://github.com/adamchainz/django-upgrade
    rev: ""  # replace with latest tag on GitHub
    hooks:
    -   id: django-upgrade
        args: [--target-version, "4.1"]   # Replace with Django version

Then, upgrade your entire project:

pre-commit run django-upgrade --all-files

Commit any changes. In the process, your other hooks will run, potentially reformatting django-upgrade’s changes to match your project’s code style.

Keep the hook installed in order to upgrade all code added to your project. pre-commit’s autoupdate command will also let you take advantage of future django-upgrade features.


Want to improve your code quality? Check out my book Boost Your Django DX which covers using pre-commit, django-upgrade, and many other tools. I wrote django-upgrade whilst working on the book!


Usage

django-upgrade is a commandline tool that rewrites files in place. Pass your Django version as <major>.<minor> to the --target-version flag. django-upgrade will run all its fixers for versions up to and including the target version. These fixers rewrite your code to avoid DeprecationWarnings and use some new features.

For example:

django-upgrade --target-version 4.1 example/core/models.py example/settings.py

The --target-version flag defaults to 2.2, the oldest supported version when this project was created. For more on usage run django-upgrade --help.

django-upgrade focuses on upgrading your code and not on making it look nice. Run django-upgrade before formatters like Black.

django-upgrade does not have any ability to recurse through directories. Use the pre-commit integration, globbing, or another technique for applying to many files. Some fixers depend on the names of containing directories to activate, so ensure you run django-upgrade with paths relative to the root of your project. For example, with git ls-files | xargs:

git ls-files -- '*.py' | xargs django-upgrade --target-version 4.1

…or PowerShell’s ForEach-Object:

git ls-files -- '*.py' | %{django-upgrade --target-version 4.1 $_}

The full list of fixers is documented below.

History

django-codemod is a pre-existing, more complete Django auto-upgrade tool, written by Bruno Alla. Unfortunately its underlying library LibCST is particularly slow, making it annoying to run django-codemod on every commit and in CI.

django-upgrade is an experiment in reimplementing such a tool using the same techniques as the fantastic pyupgrade. The tool leans on the standard library’s ast and tokenize modules, the latter via the tokenize-rt wrapper. This means it will always be fast and support the latest versions of Python.

For a quick benchmark: running django-codemod against a medium Django repository with 153k lines of Python takes 133 seconds. pyupgrade and django-upgrade both take less than 0.5 seconds.

Fixers

All Versions

The below fixers run regardless of the target version.

Versioned blocks

Removes outdated comparisons and blocks from if statements comparing to django.VERSION. Supports comparisons of the form:

if django.VERSION <comparator> (<X>, <Y>):
    ...

Where <comparator> is one of <, <= , >, or >=, and <X> and <Y> are integer literals. A single else block may be present, but elif is not supported.

-if django.VERSION < (4, 1):
-    class RenameIndex:
-        ...

-if django.VERSION >= (4, 1):
-    constraint.validate()
-else:
-    custom_validation(constraint)
+constraint.validate()

See also pyupgrade’s similar feature that removes outdated code from checks on the Python version.

Django 1.7

Release Notes

Admin model registration

Rewrites admin.site.register() calls to the new @admin.register() decorator syntax when eligible. This only applies in files that use from django.contrib import admin or from django.contrib.gis import admin.

 from django.contrib import admin

+@admin.register(MyModel1, MyModel2)
 class MyCustomAdmin(admin.ModelAdmin):
     ...

-admin.site.register(MyModel1, MyCustomAdmin)
-admin.site.register(MyModel2, MyCustomAdmin)

This also works with custom admin sites. Such calls are detected heuristically based on three criteria:

  1. The object whose register() method is called has a name ending with site.
  2. The registered class has a name ending with Admin.
  3. The filename has the word admin somewhere in its path.
from myapp.admin import custom_site
from django.contrib import admin

+@admin.register(MyModel)
+@admin.register(MyModel, site=custom_site)
class MyModelAdmin(admin.ModelAdmin):
    pass

-custom_site.register(MyModel, MyModelAdmin)
-admin.site.register(MyModel, MyModelAdmin)

If a register() call is preceded by an unregister() call that includes the same model, it is ignored.

from django.contrib import admin


class MyCustomAdmin(admin.ModelAdmin):
    ...


admin.site.unregister(MyModel1)
admin.site.register(MyModel1, MyCustomAdmin)

Django 1.9

Release Notes

on_delete argument

Add on_delete=models.CASCADE to ForeignKey and OneToOneField:

 from django.db import models

-models.ForeignKey("auth.User")
+models.ForeignKey("auth.User", on_delete=models.CASCADE)

-models.OneToOneField("auth.User")
+models.OneToOneField("auth.User", on_delete=models.CASCADE)

This fixer also support from-imports:

-from django.db.models import ForeignKey
+from django.db.models import CASCADE, ForeignKey

-ForeignKey("auth.User")
+ForeignKey("auth.User", on_delete=CASCADE)

DATABASES

Update the DATABASES setting backend path django.db.backends.postgresql_psycopg2 to use the renamed version django.db.backends.postgresql.

Settings files are heuristically detected as modules with the whole word “settings” somewhere in their path. For example myproject/settings.py or myproject/settings/production.py.

 DATABASES = {
     "default": {
-        "ENGINE": "django.db.backends.postgresql_psycopg2",
+        "ENGINE": "django.db.backends.postgresql",
         "NAME": "mydatabase",
         "USER": "mydatabaseuser",
         "PASSWORD": "mypassword",
         "HOST": "127.0.0.1",
         "PORT": "5432",
     }
 }

Compatibility imports

Rewrites some compatibility imports:

  • django.forms.utils.pretty_name in django.forms.forms
  • django.forms.boundfield.BoundField in django.forms.forms

Whilst mentioned in the Django 3.1 release notes, these have been possible since Django 1.9.

-from django.forms.forms import pretty_name
+from django.forms.utils import pretty_name

Django 1.11

Release Notes

Compatibility imports

Rewrites some compatibility imports:

  • django.core.exceptions.EmptyResultSet in django.db.models.query, django.db.models.sql, and django.db.models.sql.datastructures
  • django.core.exceptions.FieldDoesNotExist in django.db.models.fields

Whilst mentioned in the Django 3.1 release notes, these have been possible since Django 1.11.

-from django.db.models.query import EmptyResultSet
+from django.core.exceptions import EmptyResultSet

-from django.db.models.fields import FieldDoesNotExist
+from django.core.exceptions import FieldDoesNotExist

Django 2.0

Release Notes

URL’s

Rewrites imports of include() and url() from django.conf.urls to django.urls. url() calls using compatible regexes are rewritten to the new path() syntax, otherwise they are converted to call re_path().

-from django.conf.urls import include, url
+from django.urls import include, path, re_path

 urlpatterns = [
-    url(r'^$', views.index, name='index'),
+    path('', views.index, name='index'),
-    url(r'^about/$', views.about, name='about'),
+    path('about/', views.about, name='about'),
-    url(r'^post/(?P<slug>[-a-zA-Z0-9_]+)/$', views.post, name='post'),
+    path('post/<slug:slug>/', views.post, name='post'),
-    url(r'^weblog', include('blog.urls')),
+    re_path(r'^weblog', include('blog.urls')),
 ]

Existing re_path() calls are also rewritten to the path() syntax when eligible.

-from django.urls import include, re_path
+from django.urls import include, path, re_path

 urlpatterns = [
-    re_path(r'^about/$', views.about, name='about'),
+    path('about/', views.about, name='about'),
     re_path(r'^post/(?P<slug>[\w-]+)/$', views.post, name='post'),
 ]

The compatible regexes that will be converted to use path converters are the following:

  • [^/]+str
  • [0-9]+int
  • [-a-zA-Z0-9_]+slug
  • [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}uuid
  • .+path

These are taken from the path converter classes.

For some cases, this change alters the type of the arguments passed to the view, from str to the converted type (e.g. int). This is not guaranteed backwards compatible: there is a chance that the view expects a string, rather than the converted type. But, pragmatically, it seems 99.9% of views do not require strings, and instead work with either strings or the converted type. Thus, you should test affected paths after this fixer makes any changes.

Note that [\w-] is sometimes used for slugs, but is not converted because it might be incompatible. That pattern matches all Unicode word characters, such as “α”, unlike Django's slug converter, which only matches Latin characters.

lru_cache

Rewrites imports of lru_cache from django.utils.functional to use functools.

-from django.utils.functional import lru_cache
+from functools import lru_cache

<func>.allow_tags = True

Removes assignments of allow_tags attributes to True. This was an admin feature to allow display functions to return HTML without marking it as unsafe, deprecated in Django 1.9. In practice, most display functions that return HTML already use format_html() or similar, so the attribute wasn’t necessary. This only applies in files that use from django.contrib import admin or from django.contrib.gis import admin.

 from django.contrib import admin

 def upper_case_name(obj):
     ...

-upper_case_name.allow_tags = True

Django 2.2

Release Notes

HttpRequest.headers

Rewrites use of request.META to read HTTP headers to instead use request.headers. Header lookups are done in lowercase per the HTTP/2 specification.

-request.META['HTTP_ACCEPT_ENCODING']
+request.headers['accept-encoding']

-self.request.META.get('HTTP_SERVER', '')
+self.request.headers.get('server', '')

-request.META.get('CONTENT_LENGTH')
+request.headers.get('content-length')

-"HTTP_SERVER" in request.META
+"server" in request.headers

QuerySetPaginator

Rewrites deprecated alias django.core.paginator.QuerySetPaginator to Paginator.

-from django.core.paginator import QuerySetPaginator
+from django.core.paginator import Paginator

-QuerySetPaginator(...)
+Paginator(...)

FixedOffset

Rewrites deprecated class FixedOffset(x, y)) to timezone(timedelta(minutes=x), y)

Known limitation: this fixer will leave code broken with an ImportError if FixedOffset is called with only *args or **kwargs.

-from django.utils.timezone import FixedOffset
-FixedOffset(120, "Super time")
+from datetime import timedelta, timezone
+timezone(timedelta(minutes=120), "Super time")

FloatRangeField

Rewrites model and form fields using FloatRangeField to DecimalRangeField, from the relevant django.contrib.postgres modules.

 from django.db.models import Model
-from django.contrib.postgres.fields import FloatRangeField
+from django.contrib.postgres.fields import DecimalRangeField

 class MyModel(Model):
-    my_field = FloatRangeField("My range of numbers")
+    my_field = DecimalRangeField("My range of numbers")

TestCase class database declarations

Rewrites the allow_database_queries and multi_db attributes of Django’s TestCase classes to the new databases attribute. This only applies in test files, which are heuristically detected as files with either “test” or “tests” somewhere in their path.

Note that this will only rewrite to databases = [] or databases = "__all__". With multiple databases you can save some test time by limiting test cases to the databases they require (which is why Django made the change).

 from django.test import SimpleTestCase

 class MyTests(SimpleTestCase):
-    allow_database_queries = True
+    databases = "__all__"

     def test_something(self):
         self.assertEqual(2 * 2, 4)

Django 3.0

Release Notes

django.utils.encoding aliases

Rewrites smart_text() to smart_str(), and force_text() to force_str().

-from django.utils.encoding import force_text, smart_text
+from django.utils.encoding import force_str, smart_str


-force_text("yada")
-smart_text("yada")
+force_str("yada")
+smart_str("yada")

django.utils.http deprecations

Rewrites the urlquote(), urlquote_plus(), urlunquote(), and urlunquote_plus() functions to the urllib.parse versions. Also rewrites the internal function is_safe_url() to url_has_allowed_host_and_scheme().

-from django.utils.http import urlquote
+from urllib.parse import quote

-escaped_query_string = urlquote(query_string)
+escaped_query_string = quote(query_string)

django.utils.text deprecation

Rewrites unescape_entities() with the standard library html.escape().

-from django.utils.text import unescape_entities
+import html

-unescape_entities("some input string")
+html.escape("some input string")

django.utils.translation deprecations

Rewrites the ugettext(), ugettext_lazy(), ugettext_noop(), ungettext(), and ungettext_lazy() functions to their non-u-prefixed versions.

-from django.utils.translation import ugettext as _, ungettext
+from django.utils.translation import gettext as _, ngettext

-ungettext("octopus", "octopodes", n)
+ngettext("octopus", "octopodes", n)

Django 3.1

Release Notes

JSONField

Rewrites imports of JSONField and related transform classes from those in django.contrib.postgres to the new all-database versions. Ignores usage in migration files, since Django kept the old class around to support old migrations. You will need to make migrations after this fix makes changes to models.

-from django.contrib.postgres.fields import JSONField
+from django.db.models import JSONField

PASSWORD_RESET_TIMEOUT_DAYS

Rewrites the setting PASSWORD_RESET_TIMEOUT_DAYS to PASSWORD_RESET_TIMEOUT, adding the multiplication by the number of seconds in a day.

Settings files are heuristically detected as modules with the whole word “settings” somewhere in their path. For example myproject/settings.py or myproject/settings/production.py.

-PASSWORD_RESET_TIMEOUT_DAYS = 4
+PASSWORD_RESET_TIMEOUT = 60 * 60 * 24 * 4

Signal

Removes the deprecated documentation-only providing_args argument.

 from django.dispatch import Signal
-my_cool_signal = Signal(providing_args=["documented", "arg"])
+my_cool_signal = Signal()

get_random_string

Injects the now-required length argument, with its previous default 12.

 from django.utils.crypto import get_random_string
-key = get_random_string(allowed_chars="01234567899abcdef")
+key = get_random_string(length=12, allowed_chars="01234567899abcdef")

NullBooleanField

Transforms the NullBooleanField() model field to BooleanField(null=True). Ignores usage in migration files, since Django kept the old class around to support old migrations. You will need to make migrations after this fix makes changes to models.

-from django.db.models import Model, NullBooleanField
+from django.db.models import Model, BooleanField

 class Book(Model):
-    valuable = NullBooleanField("Valuable")
+    valuable = BooleanField("Valuable", null=True)

ModelMultipleChoiceField

Replace list error message key with list_invalid on forms ModelMultipleChoiceField.

-forms.ModelMultipleChoiceField(error_messages={"list": "Enter multiple values."})
+forms.ModelMultipleChoiceField(error_messages={"invalid_list": "Enter multiple values."})

Django 3.2

Release Notes

@admin.action()

Rewrites functions that have admin action attributes assigned to them to use the new @admin.action() decorator. This only applies in files that use from django.contrib import admin or from django.contrib.gis import admin.

 from django.contrib import admin

 # Module-level actions:

+@admin.action(
+    description="Publish articles",
+)
 def make_published(modeladmin, request, queryset):
     ...

-make_published.short_description = "Publish articles"

 # …and within classes:

 @admin.register(Book)
 class BookAdmin(admin.ModelAdmin):
+    @admin.action(
+        description="Unpublish articles",
+        permissions=("unpublish",),
+    )
     def make_unpublished(self, request, queryset):
         ...

-    make_unpublished.allowed_permissions = ("unpublish",)
-    make_unpublished.short_description = "Unpublish articles"

@admin.display()

Rewrites functions that have admin display attributes assigned to them to use the new @admin.display() decorator. This only applies in files that use from django.contrib import admin or from django.contrib.gis import admin.

 from django.contrib import admin

 # Module-level display functions:

+@admin.display(
+    description="NAME",
+)
 def upper_case_name(obj):
     ...

-upper_case_name.short_description = "NAME"

 # …and within classes:

 @admin.register(Book)
 class BookAdmin(admin.ModelAdmin):
+    @admin.display(
+        description='Is Published?',
+        boolean=True,
+        ordering='-publish_date',
+    )
     def is_published(self, obj):
         ...

-    is_published.boolean = True
-    is_published.admin_order_field = '-publish_date'
-    is_published.short_description = 'Is Published?'

BaseCommand.requires_system_checks

Rewrites the requires_system_checks attributes of management command classes from bools to "__all__" or [] as appropriate. This only applies in command files, which are heuristically detected as files with management/commands somewhere in their path.

 from django.core.management.base import BaseCommand

 class Command(BaseCommand):
-    requires_system_checks = True
+    requires_system_checks = "__all__"

 class SecondCommand(BaseCommand):
-    requires_system_checks = False
+    requires_system_checks = []

EmailValidator

Rewrites the whitelist keyword argument to its new name allowlist.

 from django.core.validators import EmailValidator

-EmailValidator(whitelist=["example.com"])
+EmailValidator(allowlist=["example.com"])

default_app_config

Removes module-level default_app_config assignments from __init__.py files:

-default_app_config = 'my_app.apps.AppConfig'

Django 4.0

Release Notes

USE_L10N

Removes the deprecated USE_L10N setting if set to its default value of True.

Settings files are heuristically detected as modules with the whole word “settings” somewhere in their path. For example myproject/settings.py or myproject/settings/production.py.

-USE_L10N = True

lookup_needs_distinct

Renames the undocumented django.contrib.admin.utils.lookup_needs_distinct to lookup_spawns_duplicates:

-from django.contrib.admin.utils import lookup_needs_distinct
+from django.contrib.admin.utils import lookup_spawns_duplicates

-if lookup_needs_distinct(self.opts, search_spec):
+if lookup_spawns_duplicates(self.opts, search_spec):
    ...

Django 4.1

Release Notes

django.utils.timezone.utc deprecations

Rewrites imports of django.utils.timezone.utc to use datetime.timezone.utc. Requires an existing import of the datetime module.

 import datetime
-from django.utils.timezone import utc

-calculate_some_datetime(utc)
+calculate_some_datetime(datetime.timezone.utc)
 import datetime as dt
 from django.utils import timezone


-do_a_thing(timezone.utc)
+do_a_thing(dt.timezone.utc)

assertFormError() and assertFormsetError()

Rewrites calls to these test case methods from the old signatures to the new ones.

-self.assertFormError(response, "form", "username", ["Too long"])
+self.assertFormError(response.context["form"], "username", ["Too long"])

-self.assertFormError(response, "form", "username", None)
+self.assertFormError(response.context["form"], "username", [])

-self.assertFormsetError(response, "formset", 0, "username", ["Too long"])
+self.assertFormsetError(response.context["formset"], 0, "username", ["Too long"])

-self.assertFormsetError(response, "formset", 0, "username", None)
+self.assertFormsetError(response.context["formset"], 0, "username", [])

Django 4.2

Release Notes

STORAGES setting

Combines deprecated settings DEFAULT_FILE_STORAGE and STATICFILES_STORAGE into the new STORAGES setting, within settings files. Only applies if all old settings are defined as strings, at module level, and a STORAGES setting hasn’t been defined.

Settings files are heuristically detected as modules with the whole word “settings” somewhere in their path. For example myproject/settings.py or myproject/settings/production.py.

-DEFAULT_FILE_STORAGE = "example.storages.ExtendedFileSystemStorage"
-STATICFILES_STORAGE = "example.storages.ExtendedS3Storage"
+STORAGES = {
+    "default": {
+        "BACKEND": "example.storages.ExtendedFileSystemStorage",
+    },
+    "staticfiles": {
+        "BACKEND": "example.storages.ExtendedS3Storage",
+    },
+}

If the module has a from ... import * with a module path mentioning “settings”, django-upgrade makes an educated guess that a base STORAGES setting is imported from there. It then uses ** to extend that with any values in the current module:

 from example.settings.base import *
-DEFAULT_FILE_STORAGE = "example.storages.S3Storage"
+STORAGES = {
+    **STORAGES,
+    "default": {
+        "BACKEND": "example.storages.S3Storage",
+    },
+}

Test client HTTP headers

Transforms HTTP headers from the old WSGI kwarg format to use the new headers dictionary, for:

  • Client method like self.client.get()
  • Client instantiation
  • RequestFactory instantiation

Requires Python 3.9+ due to changes in ast.keyword.

-response = self.client.get("/", HTTP_ACCEPT="text/plain")
+response = self.client.get("/", headers={"accept": "text/plain"})

 from django.test import Client
-Client(HTTP_ACCEPT_LANGUAGE="fr-fr")
+Client(headers={"accept-language": "fr-fr"})

 from django.test import RequestFactory
-RequestFactory(HTTP_USER_AGENT="curl")
+RequestFactory(headers={"user-agent": "curl"})

assertFormsetError and assertQuerysetEqual

Rewrites calls to these test case methods from the old names to the new ones with capitalized “Set”.

-self.assertFormsetError(response.context["form"], "username", ["Too long"])
+self.assertFormSetError(response.context["form"], "username", ["Too long"])

-self.assertQuerysetEqual(authors, ["Brad Dayley"], lambda a: a.name)
+self.assertQuerySetEqual(authors, ["Brad Dayley"], lambda a: a.name)

More Repositories

1

django-cors-headers

Django app for handling the server headers required for Cross-Origin Resource Sharing (CORS)
Python
5,087
star
2

django-htmx

Extensions for using Django with htmx.
JavaScript
866
star
3

django-mysql

🐬 🐴 Extensions to Django for use with MySQL/MariaDB
Python
535
star
4

blacken-docs

Run `black` on python code blocks in documentation files
Python
513
star
5

time-machine

Travel through time in your tests.
Python
447
star
6

flake8-comprehensions

❄️ A flake8 plugin to help you write better list/set/dict comprehensions.
Python
446
star
7

django-perf-rec

Keep detailed records of the performance of your Django code.
Python
330
star
8

django-browser-reload

Automatically reload your browser in development.
Python
296
star
9

mac-ansible

🐄 Configuring my mac with Ansible
Shell
170
star
10

patchy

⚓ Patch the inner source of python functions at runtime.
Python
163
star
11

apig-wsgi

Wrap a WSGI application in an AWS Lambda handler function for running on API Gateway or an ALB.
Python
146
star
12

django-linear-migrations

Ensure your migration history is linear.
Python
136
star
13

treepoem

Barcode rendering for Python supporting QRcode, Aztec, PDF417, I25, Code128, Code39 and many more types.
PostScript
115
star
14

ec2-metadata

An easy interface to query the EC2 metadata API, with caching.
Python
102
star
15

django-rich

Extensions for using Rich with Django.
Python
90
star
16

django-permissions-policy

Set the draft security HTTP header Permissions-Policy (previously Feature-Policy) on your Django app.
Python
81
star
17

django-watchfiles

Use watchfiles in Django’s autoreloader.
Python
81
star
18

django-read-only

Disable Django database writes.
Python
75
star
19

django-minify-html

Use minify-html, the extremely fast HTML + JS + CSS minifier, with Django.
Python
73
star
20

flake8-tidy-imports

❄️ A flake8 plugin that helps you write tidier imports.
Python
60
star
21

heroicons

Use heroicons in your Django and Jinja templates.
Python
58
star
22

SublimeFiglet

Add in ASCII text art from "figlet"
Python
46
star
23

lifelogger

📅 Track your life like a pro on Google Calendar via your terminal.
Python
40
star
24

pip-lock

Check for differences between requirements.txt files and your environment
Python
36
star
25

django-capture-on-commit-callbacks

Capture and make assertions on transaction.on_commit() callbacks.
Python
35
star
26

django-version-checks

System checks for your project's environment.
Python
34
star
27

django-jsonfield

(Maintenance mode only) Cross-database JSON field for Django models.
Python
30
star
28

unittest-parametrize

Parametrize tests within unittest TestCases.
Python
29
star
29

scripts

Useful little scripts that I use on commandline. Work in OS-X + zsh at least.
Shell
27
star
30

multilint

✅ Run multiple python linters easily
Python
27
star
31

flake8-no-pep420

A flake8 plugin to ban PEP-420 implicit namespace packages.
Python
22
star
32

django-startproject-templates

Python
22
star
33

pytest-is-running

pytest plugin providing a function to check if pytest is running.
Python
21
star
34

SublimeHTMLMustache

✏️ Adds HTML Mustache as a language to Sublime Text 2/3, with snippets.
19
star
35

pytest-reverse

Pytest plugin to reverse test order.
Python
19
star
36

owela-club

Play the Namibian game of Owela against a terrible AI. Built using Django and htmx.
Python
18
star
37

nose-randomly

👃 Nose plugin to randomly order tests and control `random.seed`
Python
17
star
38

talk-how-to-hack-a-django-website

JavaScript
14
star
39

dynamodb_utils

A toolchain for Amazon's DynamoDB to make common operations (backup, restore backups) easier.
Python
12
star
40

sound-resynthesis

🔈 Sound Resynthesis with a Genetic Algorithm - my final year project from university
Java
12
star
41

mariadb-dyncol

💾 Python dicts <-> MariaDB Dynamic Column binary format
Python
11
star
42

pre-commit-oxipng

Mirror of oxipng for pre-commit.
Rust
11
star
43

pytest-flake8dir

❄️ A pytest fixture for testing flake8 plugins.
Python
11
star
44

logentries-cli

📒 Get your logs from Logentries on the comandline.
Python
10
star
45

pre-commit-dprint

Mirror of dprint for pre-commit.
9
star
46

sublime-rst-improved

Python
8
star
47

h

Python
8
star
48

talk-improve-startup-time

“How to profile and improve startup time” talk
JavaScript
8
star
49

sublime_text_settings

✏️ My settings for sublime text 3 - as in Packages/User
Python
8
star
50

talk-django-and-htmx

JavaScript
7
star
51

django-settings-file

Python
7
star
52

tox-py

Adds the --py flag to tox to run environments matching a given Python interpreter.
Python
6
star
53

kwargs-only

A decorator to make a function accept keyword arguments only, on both Python 2 and 3.
Python
6
star
54

pytest-super-check

🔒 Pytest plugin to ensure all your TestCase classes call super() in setUp, tearDown, etc.
Python
6
star
55

django_atomic_celery

Atomic transaction aware Celery tasks for Django
Python
6
star
56

django-coverage-example

Python
5
star
57

django-pymysql-backend

A Django database backend for MySQL using PyMySQL.
Python
5
star
58

pytest-restrict

🔒 Pytest plugin to restrict the test types allowed
Python
5
star
59

talk-data-oriented-django

JavaScript
4
star
60

talk-speed-up-your-tests-with-setuptestdata

JavaScript
4
star
61

talk-django-and-web-security-headers

JavaScript
3
star
62

fluentd.tmLanguage

Syntax highlighting for Fluentd configuration files
3
star
63

django-ticket-33153

https://code.djangoproject.com/ticket/33153
Python
3
star
64

pytest-flake8-path

A pytest fixture for testing flake8 plugins.
Python
3
star
65

django_atomic_signals

Signals for atomic transaction blocks in Django 1.6+
Python
3
star
66

flake8-no-types

A flake8 plugin to ban type hints.
Python
3
star
67

SublimeMoveTabs

✏️ A short plugin for Sublime Text 2 that allows rearrangement of tabs/'views' with the keyboard.
Python
3
star
68

dynamodb_local_utils

Automatically run DynamoDB Local on Mac OS X
Shell
3
star
69

pygments-git

Pygments lexers for Git output and files
Python
3
star
70

workshop-evenergy-concurrency-and-parallelism

Python
2
star
71

talk-how-complex-systems-fail

Talk for the Papers We Love London meetup
TeX
2
star
72

google_lifelog

Making a lifelog on google calendar.
Python
2
star
73

talk-building-interactive-pages-with-htmx

JavaScript
2
star
74

workshop-idiomatic-python

Python
2
star
75

ansible-talk-custom-template-filters

My talk for the Ansible London Meetup in March 2015
TeX
2
star
76

talk-django-vs-flask

JavaScript
2
star
77

django-talk-factory-boy

Talk for London Django Meetup
TeX
2
star
78

ProgrammingInterview

Solving the problems posted on ProgrammingInterview on YouTube
Python
2
star
79

example-pre-commit-ci-lite

example
2
star
80

django-server-push-demo

Python
2
star
81

talk-django-capture-on-commit-callbacks

JavaScript
2
star
82

techblog

Filled with little coding notes and fixes.
2
star
83

adamchainz

👋
Python
2
star
84

SublimeCowsay

✏️🐮 A silly little Sublime Text plugin for 2 and 3 to allow you to quickly convert a text selection to a cow speech bubble via the brilliant cowsay utility.
Python
2
star
85

djceu2019-workshop

Python
2
star
86

talk-what-happens-when-you-run-manage.py-test

JavaScript
2
star
87

talk-technologies-that-will-be-around-in-21-years

JavaScript
2
star
88

django-demo-constraint-single-column-not-null

Python
2
star
89

django-harlequin

Launch Harlequin, the SQL IDE for your Terminal, with your Django database configuration.
Python
2
star
90

channels-bug-connection-closed

Reproduction for Channels bug
Python
1
star
91

workshop-concurrency-and-parallelism

Python
1
star
92

django-talk-duth

Django Under The Hood 2015 Summary
TeX
1
star
93

workshop-rest-api-django

Python
1
star
94

workshop-recommended-practices

Python
1
star
95

talk-django-3.2-test-features

JavaScript
1
star
96

workshop-profiling-and-debugging

Python
1
star
97

django-feature-policy-shim

1
star
98

kvkit

high-level python toolkit for ordered key/value stores
Python
1
star
99

phabricator-csv-import

Python
1
star
100

django-blue-green-example

Reproducing the technique from “Smooth Database Changes in Blue-Green Deployments” by Mariusz Felisiak.
Python
1
star