Package: django-nps
# Django NPSDjango app supporting Net Promoter Score (NPS) surveys## CompatibilityThis package support Django 3.2+, Python 3.8+.## Background - Net Promoter ScoreThe NPS is a measure of customer loyalty that is captured by asking yourcustomers a singe question:> How likely is it that you would recommend our> [company|product|service] to a friend or colleague?"The answer to this question is a number from 0-10 (inclusive). These scoresare then broken out into three distinct groups: 'detractors' (0-6), 'neutral'(7-8) and 'promoters' (9-10). The NPS is then the difference between thenumber of promoters and detractors (as a percentage of the whole population).For example, if you ask 100 people, and you get the following results:```detractors: 20%neutrals:   10%promoters:  70%```Then your NPS is 70 - 20 = 50. *(NPS is expressed as a number, not a %)*NPS was orginally developed at the strategy consultants Bain & Companyby Fred Reichheld in 2003. They retain the registered trademark for NPS,and you can read all about the history of it on their site "[Net Promoter System](http://netpromotersystem.com/about/index.aspx)".## UsageThis app is used to store the individual scores, and calculate the NPSbased on these. It does not contain any templates for displaying thequestion itself, neither does it put any restriction around how oftenyou ask the question, or to whom. It is up to the app developer todetermine how this should work - each score is timestamped and linked toa Django User object, so you can easily work out the time elapsed sincethe last time they were asked.For example, if you want to ensure that you only survey users every X days,you can add a context property to the template using the `display_to_user`method:```python>>> # only show the survey every 90 days>>> UserScore.objects.days_since_user_score(request.user) > 90True```If you then show the survey - the output of which is a single value (thescore) together with an optional reason ("what is the main reason foryour score"), is then posted to the ``post_score`` endpoint, whichregisters the user score.The NPS value itself can be calculated on any queryset of ``UserScore``objects - which allows you to track the score based on any attribute ofthe score itself or the underlying user. For instance, if you havecustom user profiles, you may wish to segement your NPS bycharacteristics of those profiles.```python>>> # December's NPS>>> UserScore.objects.filter(timestamp__month=12).net_promoter_score()50```The `post_score` endpoint returns a `JsonResponse` which contains a`'success': True|False` value together with the `UserScore` details:```python{"success": True,"score": {"id": 1, "user": 1, "score": 0, "group": "detractor"}}```If the score was rejected, the errors are returned in place of the score (errorsare a list of lists, as returned from the Django `Form.errors` property):```python{"success": False,"errors": [["score", "Score must be between 0-10"]]}```The app contains a piece of middleware, `NPSMiddleware`, which will add anattribute to the `HttpRequest` object called `show_nps`. If you add themiddleware to your settings:```python# settings.pyMIDDLEWARE_CLASSES = (# standard django middleware'django.middleware.common.CommonMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware',...'net_promoter_score.NPSMiddleware',)```You can then use this value in your templates:```html<!-- show_nps template = {{request.show_nps}} -->{% if request.show_nps %}<div>HTML goes here</div>{% endif %}```## Settings**NPS_DISPLAY_INTERVAL**The number of days between surveys, integer, defaults to 30. This value is usedby the default `show_nps` function to determine whether someone should be shownthe survey.**NPS_DISPLAY_FUNCTION**A function that takes an `HttpRequest` object as its only argument, and whichreturns True if you want to show the survey. This function is used by the`net_promoter_score.show_nps` function. It defaults to return True if therequest user has either never seen the survey, or hasn't seen it for more daysthan the `NPS_DISPLAY_INTERVAL`.This function should be overridden if you want fine-grained control overthe process - it's the main hook into the app.## TestsThere is a full suite of tests for the app, which are best run through `tox`. Ifyou wish to run the tests outside of tox, you should install the requirements first:```$ pip install -r requirements.txt$ python manage.py test```## LicenseMIT## ContributingUsual rules apply:1. Fork to your own account2. Create a branch, fix the issue / add the feature3. Submit PRPlease take care to follow the coding style - and PEP8.## AcknowledgementsCredit is due to **epantry** for the [original project](https://github.com/epantry/django-netpromoterscore) from which this was forked.Thanks also to the kind people at **Eldarion** ([website](http://eldarion.com/))for releasing the PyPI package name.