Your Django code review copilot

Code Review Doctor suggests Django improvements right inside your pull request.

django-doctorbotsuggested changes just now
migration.py
1
+
class Migration(migrations.Migration):
2
+
    dependencies = [("core", "0001_initial.py")]
3
+
    operations = [RunPython(forwards)]
Suggested changes
-
    operations = [RunPython(forwards)]
+
    operations = [RunPython(forwards, RunPython.noop)]
Commit suggestion

It's good to, as a minimum, specify noop in RunPython so the migration can be skipped when going backwards, and even better to specify a function that undoes the migration.

Read more
template.html
1
+
<img src="/static/logo.png" />
Suggested changes
-
<img src="/static/logo.png" />
+
{% load static %}
+
<img src="{% static 'logo.png' %}" />
Commit suggestion

Hard-coding static asset urls is brittle because the place the files are stored depends on the `STATICFILES_STORAGE` used - so if in prod the storage backend uploads to S3 or even renames the file then this hard-coded URL will break.

Using "{% static ... %}" solves that as it knows exactly where the files are stored.

Read more
tasks.py
1
+
def trigger_tasks(queryset):
2
+
    for item in queryset:
3
+
        run_async_task(item.page.id)
Suggested changes
-
        run_async_task(item.page.id)
+
        run_async_task(item.page_id)
Commit suggestion

When working with foreign keys, accessing the related field will result in a database read. That can be eliminated by using *_id, which is the foreign key value that Django has already cached on the object to make this scenario more efficient.

Read more
settings.py
1
+
MIDDLEWARE = [
2
+
    'django.middleware.common.CommonMiddleware',
3
+
    'django.contrib.sessions.middleware.SessionMiddleware',
4
+
    ...
Suggested changes
+
    'django.middleware.csrf.CsrfViewMiddleware',
Expand 2 lines ...
Commit suggestion

Your website is vulnerable to CSRF attacks because the MIDDLEWARE setting is missing CsrfViewMiddleware - so a hacker can fool your website into thinking a request is coming from a logged in user.

Read more
5
+
]
views.py
1
+
def my_view(request):
2
+
    url = reverse_lazy('foo')
Suggested changes
-
    url = reverse_lazy('foo')
+
    url = reverse('foo')
Commit suggestion

Using reverse(...) is better than using reverse_lazy(...) when the url is being reversed after URLConf has been loaded.

Read more
Update views.py
Over 3000 teams use Code Review Doctor to write better code, release faster, and save time.
  • Department for International Trade
  • Giant
  • Motley fool
  • Lift Interactive
  • Lightmatter
  • Media Interactive
  • We Make Services
  • Sumo

Cleaner and safer code

Code Review Doctor reviews your GitHub pull requests to prevent adding vulnerabilities, performance, or maintainability issues to your code. The code review runs in the cloud so there is nothing to install locally. Cutting edge technology achieves near-zero noise for developers so you can follow best practices without changing how you work.

"Extremely positive. Suggested useful changes, giving our senior developers time back."

Jon Atkinson, Technical Director at Giant

More than a linter

Code Review Doctor gives clear and actionable advice, which you can commit to your branch directly from your pull request. No more waiting the CI build to finish then reading error logs, tabbing to your text editor, committing the fixes and pushing. Accept the changes right inside your pull request with no context switching.
344
+
from django.conf import settings
345
+
from django.contrib import admin
346
+
347
+
	
348
+
urlpatterns = [...]
349
+
	
350
+
if settings.DEBUG:
Suggested changes
-
if settings.DEBUG:
+
if settings.FEATURE_ADMIN_ENABLED:
Expand 2 lines ...
Commit suggestion

Your code is harder to test in isolation because the value of settings.DEBUG affects other Django behaviours including error handling. Consider using a feature flag instead.

Read more
351
+
    # not exposing admin to prod so it can't be hacked
352
+
    urlpatterns.append(path('admin/', admin.site.urls))
Enforce best practice. Skip the docs and stay confident you're following best practice. With Code Review Doctor you stay focused right in your pull request.
344
+
def task(admin_blog_ids):
345
+
    queryset = CommentModel.objects.all()
346
+
    if len(queryset) > 100:
Suggested changes
-
    if len(queryset) > 100:
+
    if queryset.count() > 100:
Commit suggestion

len(queryset) performs the count at application level. That is much less efficient than doing queryset.count(), which does the calculation at database level and just returns the count.

Read more
347
+
        send_email_to_admin(queryset)
344
+
from example.config import settings
Suggested changes
-
from example.config import settings
+
from django.conf import settings
Commit suggestion

Using from django.conf import settings simplifies the code and makes it more maintainable.

Read more
345
+
from django.db import models
Reclaim time. Code Review Doctor works great for quickly detecting mistakes humans might miss, and even links you to the deep archive of best practice articles to upskill devs.
Prevent bugs. Code Review Doctor knows when code looks fishy and will raise the alarm. With Code Review Doctor you can deploy to prod knowing you've got a code reviewer on your side with the consistency and concentration of a robot.
344
+
urlpatterns = [
345
+
    path('', Home.as_view(), name="index"),
346
+
    path('index/', Index.as_view(), name="index"),
Suggested changes
-
    path('index/', Index.as_view(), name="index"),
+
    path('index/', Index.as_view(), name="index-list"),
Commit suggestion

URL names must be unique otherwise reverse('url_name') and {% url 'url_name' %} will link to the "wrong" page half of the time.

Read more
347
+
]

Improve your productivity

Simplify upgrading Django with our changelog comparison tool. View all changes between two releases: bug fixes, features, and deprecations all in one place rather than manually tabbing through multiple release notes and risking missing something important.

Our price

Individual

Free

forever

Protects every PR: Yes

Suggests the fix: Yes

Codebase audit: Yes

Public repositories: Unlimited

Private repositories: No

Support: No

Add to GitHub
Popular

Organization

$49

per month

Protects every PR: Yes

Suggests the fix: Yes

Codebase audit: Yes

Public repositories: Unlimited

Private repositories: 10

Support: 24/7 email and chat

Unlimited

$99

per month

Protects every PR: Yes

Suggests the fix: Yes

Codebase audit: Yes

Public repositories: Unlimited

Private repositories: Unlimited

Support: 24/7 email and chat