create a points system for django project

created at March 5, 2021, 3:03 p.m.

This article will show you how to create a minimal points/reputation system in our django project, which would be commonly used in open blog, Q&A project.

points system for django project

say we want our users to have awards (points) every time when they publish an article or answer a question.

since points are tied to users, so we can directly add a field to our User Model:

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
       ...
    points = models.PositiveIntegerField(default=0, verbose_name="points")

then make migrations:

python3 manage.py makemigrations
python3 manage.py migrate

also we need to create a function to change the points number of the points field:

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
       ...
    points = models.PositiveIntegerField(default=0, verbose_name="points")    

    ...
    def modify_points(self, added_points):
        self.points += added_points
        self.save()

reward mechanism

For example, we want users get 5 points every time when they write an article in our site, we can write in our settings.py like this:

POINTS_SETTINGS={
    "CREATE_ARTICLE":5,
    "ANSWER_QUESTION":4,
    ...
}

so that users get different scores when they have different actions in our site.

save and change the scores

let's see this image, now I didn't launch the points system, so this user have zero score even  she has  already published an article

now, we are going to rewrite the save method in our blog method, so that when a blog is created and saved, points are awarded to the composer:

from our_project.users.models import User

class Blog(models.Model):
    user=models.ForeignKey(User, on_delete=models.CASCAD, related_name="article_author", verbose_name="author")
    ...

    def save(self, *args, **kwargs):
        try:
            points = settings.POINTS_SETTINGS['CREATE_ARTICLE']
        except KeyError:
            points = 0
        User.objects.get(pk=self.user_id).modify_points(points)
        super(Blog, self).save(*args, **kwargs)

save and test

after doing changes above, you should restart your django project

now after this user created this article, her points has changed:

A Bug

this system would add points to an user when he/she re-edit his/her article and save the change.

we should add a conditional statement to add points:

    def save(self, *args, **kwargs):
        if not self.pk:
            try:
                points = settings.POINTS_SETTINGS['CREATE_ARTICLE']
            except KeyError:
                points = 0
            User.objects.get(pk=self.user_id).modify_points(points)
        super(Blog, self).save(*args, **kwargs)

our points system will only work under condition if not self.pk, which means if an article has been saved once before (a pk was generated for this article), we won't add points when this article is saved again.

Please log in to leave a comment.