diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b2f4c009357ff738a45f0edd40bdd00f00fb1899
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,8 @@
+repos:
+-   repo: local
+    hooks:
+    -   id: prospector
+        name: prospector
+        entry: ./pre-commit-scripts/prospector.sh
+        language: script
+        types: [python]
diff --git a/backend/.pylintrc b/backend/.pylintrc
deleted file mode 100644
index dc0fdb2dc4da190c837ce47ca197e7bd4ffe95ab..0000000000000000000000000000000000000000
--- a/backend/.pylintrc
+++ /dev/null
@@ -1,143 +0,0 @@
-[MASTER]
-
-# Add files or directories to the blacklist. They should be base names, not
-# paths.
-ignore=CVS, migrations, static, env, docs, manage.py
-
-# Add files or directories matching the regex patterns to the blacklist. The
-# regex matches against base names, not paths.
-ignore-patterns=
-
-# Python code to execute, usually for sys.path manipulation such as
-# pygtk.require().
-#init-hook=
-
-# Use multiple processes to speed up Pylint.
-jobs=4
-
-# Pickle collected data for later comparisons.
-persistent=yes
-
-# When enabled, pylint would attempt to guess common misconfiguration and emit
-# user-friendly hints instead of false-positive error messages
-suggestion-mode=yes
-
-# Allow loading of arbitrary C extensions. Extensions are imported into the
-# active Python interpreter and may run arbitrary code.
-unsafe-load-any-extension=no
-
-# List of plugins (as comma separated values of python modules names) to load,
-# usually to register additional checkers.
-load-plugins=pylint_django
-
-[MESSAGES CONTROL]
-
-# Disable the message, report, category or checker with the given id(s). You
-# can either give multiple identifiers separated by comma (,) or put this
-# option multiple times (only on the command line, not in the configuration
-# file where it should appear only once).You can also use "--disable=all" to
-# disable everything first and then reenable specific checks. For example, if
-# you want to run only the similarities checker, you can use "--disable=all
-# --enable=similarities". If you want to run only the classes checker, but have
-# no Warning level messages displayed, use"--disable=all --enable=classes
-# --disable=W"
-disable=print-statement,
-        parameter-unpacking,
-        unpacking-in-except,
-        old-raise-syntax,
-        backtick,
-        long-suffix,
-        old-ne-operator,
-        old-octal-literal,
-        import-star-module-level,
-        non-ascii-bytes-literal,
-        raw-checker-failed,
-        bad-inline-option,
-        locally-disabled,
-        locally-enabled,
-        file-ignored,
-        suppressed-message,
-        useless-suppression,
-        deprecated-pragma,
-        apply-builtin,
-        basestring-builtin,
-        buffer-builtin,
-        cmp-builtin,
-        coerce-builtin,
-        execfile-builtin,
-        file-builtin,
-        long-builtin,
-        raw_input-builtin,
-        reduce-builtin,
-        standarderror-builtin,
-        unicode-builtin,
-        xrange-builtin,
-        coerce-method,
-        delslice-method,
-        getslice-method,
-        setslice-method,
-        no-absolute-import,
-        old-division,
-        dict-iter-method,
-        dict-view-method,
-        next-method-called,
-        metaclass-assignment,
-        indexing-exception,
-        raising-string,
-        reload-builtin,
-        oct-method,
-        hex-method,
-        nonzero-method,
-        cmp-method,
-        input-builtin,
-        round-builtin,
-        intern-builtin,
-        unichr-builtin,
-        map-builtin-not-iterating,
-        zip-builtin-not-iterating,
-        range-builtin-not-iterating,
-        filter-builtin-not-iterating,
-        using-cmp-argument,
-        eq-without-hash,
-        div-method,
-        idiv-method,
-        rdiv-method,
-        exception-message-attribute,
-        invalid-str-codec,
-        sys-max-int,
-        bad-python3-import,
-        deprecated-string-function,
-        deprecated-str-translate-call,
-        deprecated-itertools-function,
-        deprecated-types-field,
-        next-method-defined,
-        dict-items-not-iterating,
-        dict-keys-not-iterating,
-        dict-values-not-iterating
-
-[REPORTS]
-
-# Tells whether to display a full report or only the messages
-reports=yes
-
-# Activate the evaluation score.
-score=yes
-
-
-[REFACTORING]
-
-# Maximum number of nested blocks for function / method body
-max-nested-blocks=5
-
-
-[LOGGING]
-
-# Logging modules to check that the string format arguments are in logging
-# function parameter format
-logging-modules=logging
-
-
-[FORMAT]
-
-# Maximum number of characters on a single line.
-max-line-length=100
diff --git a/backend/core/views.py b/backend/core/views.py
index 20f185b4f5ba84513c37fdf1d9fc0e91d6cdd66e..2932ec09bb16aebe08c22bfdfa567ca288d737fd 100644
--- a/backend/core/views.py
+++ b/backend/core/views.py
@@ -9,6 +9,7 @@ from core.serializers import (FeedbackSerializer, StudentSerializer,
 log = logging.getLogger(__name__)
 
 
+
 class StudentApiView(RetrieveAPIView):
     permission_classes = (IsStudent,)
 
diff --git a/backend/delbert.py b/backend/delbert.py
index 0a478a2d796276259fcc2fc6b0ebba6f688a4c42..557260f5c0a257d7d76e6fbfca6304aae899b10c 100644
--- a/backend/delbert.py
+++ b/backend/delbert.py
@@ -16,7 +16,6 @@ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'grady.settings')
 django.setup()
 
 
-
 def parseme():
     parser      = argparse.ArgumentParser()
     subparsers  = parser.add_subparsers(dest="command")
@@ -84,7 +83,7 @@ def parseme():
     return parser.parse_args()
 
 
-def handle_passwordlist(output=sys.stdout, instance="", **kwargs):
+def handle_passwordlist(output=sys.stdout, instance=""):
     with open('/usr/share/dict/words') as words:
         choose_from = list({word.strip().lower()
                             for word in words if 5 < len(word) < 8})
@@ -102,7 +101,7 @@ def handle_passwordlist(output=sys.stdout, instance="", **kwargs):
                          student.user.username, password, instance])
 
 
-def handle_enableusers(switch, exclude, include, **kwargs):
+def handle_enableusers(switch, exclude, include):
 
     if include:
         for user in User.objects.filter(username__in=include):
@@ -114,7 +113,7 @@ def handle_enableusers(switch, exclude, include, **kwargs):
             user.save()
 
 
-def handle_replaceusernames(matno2username_dict, **kwargs):
+def handle_replaceusernames(matno2username_dict):
     matno2username = json.JSONDecoder().decode(matno2username_dict.read())
     for student in Student.objects.all():
         if student.matrikel_no in matno2username:
@@ -123,12 +122,12 @@ def handle_replaceusernames(matno2username_dict, **kwargs):
             student.user.save()
 
 
-def handle_extractsubmissions(output, **kwargs):
+def handle_extractsubmissions():
     for submission in Submission.objects.filter(feedback__isnull=False).order_by('type'):
         print(submission.feedback.score, repr(submission.text), file=open(str(submission.type).replace(' ', '_'), 'a'))
 
 
-def handle_importer(**kwargs):
+def handle_importer():
     util.importer.start()
 
 def main():
diff --git a/backend/requirements.txt b/backend/requirements.txt
index d035c1effbd4e161ec2d139f5398ae54073ebee1..9f84b378ab58611f325b862ad2fb964b3d9144cd 100644
--- a/backend/requirements.txt
+++ b/backend/requirements.txt
@@ -9,3 +9,4 @@ xlrd~=1.0.0
 pytest-cov~=2.5.1
 prospector~=0.12.7
 django-cors-headers~=2.1.0
+pre-commit~=1.4.1
\ No newline at end of file
diff --git a/pre-commit-scripts/prospector.sh b/pre-commit-scripts/prospector.sh
new file mode 100755
index 0000000000000000000000000000000000000000..dd41b303bcb966282958a05885d2e9344ba84eb4
--- /dev/null
+++ b/pre-commit-scripts/prospector.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+cd backend
+unset GIT_DIR
+
+diff_files="$(git diff  --cached --name-only --relative --diff-filter=AM)" 
+if [ -n "$diff_files" ]; then
+	prospector --uses django $diff_files
+else
+	exit 0
+fi
\ No newline at end of file