With this command you can calculate the maintainability index for your whole project.
In your settings you have to add a dictionary called `RADON_MI_SETTINGS`. It could be like this:
```python
RADON_MI_SETTINGS = {
'paths': ['projectname'],
'exclude': 'projectname/some_app/some_file.py',
'ignore': 'migrations,tests',
}
```
I had to add following packages:
```
radon==3.0.1
progress==1.5
plotly==3.7.0
GitPython==2.1.11
```
Following commands are available:
* `python manage.py calculate_maintainability_index`
Only display the maintainability index of the project. The average from every file is build by using the logical lines of code per file.
* `python manage.py calculate_maintainability_index --init`
Go through every commit filtered by their commit_message (is set to “bump version” currently) and calculate the maintainability index for the whole project. This creates a file with the history.
* `python manage.py calculate_maintainability_index --showhistory`
Display the history of the maintainability_index in a graph in your browser.
* `python manage.py calculate_maintainability_index --commit`
Calculate the current maintainability_index and append it to your history. Commit your edited history file.
* `python manage.py calculate_maintainability_index --fail`
Calculate the current maintainability_index and raise an Error, if it is lower than the last entry in your history. Useful for use in an automated pipeline.
Hints:
* radon has a problem with large lists and dictionaries. If you have a file with a list or dictionary with more than 100 entries, you should exclude it.
* To initialize your history you should change the commitmessage filter to something, that suits your needs.
Created by Martin Becker at [Jonas und der Wolf GmbH](https://www.jonasundderwolf.de)
- django
- command
- git
- maintainability
If you are like me and you find yourself often using M2M fields for tons of other on-model methods, in templates, and views alike, try using this quick and dirty caching. I show the use of a "through" model for the m2m, but that is purely optional. For example, let's say we need to do several different things with our list of beads, the old way is...
# views.py
necklace = Necklace.objects.get(id=1)
bead = Bead.objects.get(id=1)
if bead in necklace.beads.all():
# this bead is here!
# template necklace.html
{% for bead in necklace.beads.all %}
<li>{{ bead }}</li>
{% endfor %}
...which would hit the database twice. Instead, we do this:
# views.py
necklace = Necklace.objects.get(id=1)
bead = Bead.objects.get(id=1)
if bead in necklace.get_beads():
# this bead is here!
# template necklace.html
{% for bead in necklace.get_beads %}
<li>{{ bead }}</li>
{% endfor %}
Which only does one hit on the database. While we could have easily set the m2m query to a variable and passed it to the template to do the same thing, the great thing is how you can build extra methods on the model that use the m2m field but share the cache with anyone down the line using the same m2m field.
I'm by no means an expert, so if there is something here I've done foolishly, let me know.