diff --git a/app/forms.py b/app/forms.py
index 64a096e421bf1aacaa9b648b8d869f1c0adfb4e3..84facd1f2e25e18920754b7cd44a6396e7e1f4fe 100644
--- a/app/forms.py
+++ b/app/forms.py
@@ -1,6 +1,6 @@
 from django import forms
 
-from app.models import Materi,Category
+from app.models import Materi, Category, RatingContributor
 from authentication.models import User
 
 
@@ -43,3 +43,21 @@ class SuntingProfilForm(forms.ModelForm):
             
 
         self.fields["email"].widget.attrs["readonly"] = True
+
+
+class RatingContributorForm(forms.ModelForm):
+    class Meta:
+        model = RatingContributor
+        fields = ['score', 'user']
+        SCORE_CHOICE = (
+            ('', 'Select score'),
+            ('1', '1'),  # First one is the value of select option and second is the displayed value in option
+            ('2', '2'),
+            ('3', '3'),
+            ('4', '4'),
+            ('5', '5'),
+        )
+        widgets = {
+            'score': forms.Select(choices=SCORE_CHOICE, attrs={'class': 'form-control'},),
+            'user': forms.HiddenInput()
+        }
diff --git a/app/migrations/0016_ratingcontributor.py b/app/migrations/0016_ratingcontributor.py
new file mode 100644
index 0000000000000000000000000000000000000000..86d787f0b6a357456c259f9842dfd7e3b7e49415
--- /dev/null
+++ b/app/migrations/0016_ratingcontributor.py
@@ -0,0 +1,25 @@
+# Generated by Django 3.1.1 on 2020-10-05 14:41
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('app', '0015_reqmaterial'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='RatingContributor',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('timestamp', models.DateTimeField(auto_now=True)),
+                ('score', models.IntegerField()),
+                ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+            ],
+        ),
+    ]
diff --git a/app/migrations/0017_auto_20201005_2145.py b/app/migrations/0017_auto_20201005_2145.py
new file mode 100644
index 0000000000000000000000000000000000000000..732caef72a1b44acef70e15c4d29b91a5df106b2
--- /dev/null
+++ b/app/migrations/0017_auto_20201005_2145.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.1.1 on 2020-10-05 14:45
+
+import django.core.validators
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('app', '0016_ratingcontributor'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='ratingcontributor',
+            name='score',
+            field=models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(5)]),
+        ),
+    ]
diff --git a/app/models.py b/app/models.py
index 12366f8ed831dff40a63c675c93e5da4d96bfcd8..54e05f404d9b68827b86d9ce247a2f7873caa26c 100644
--- a/app/models.py
+++ b/app/models.py
@@ -1,6 +1,7 @@
 import random
 
 from django.core.exceptions import ValidationError
+from django.core.validators import MinValueValidator, MaxValueValidator
 from django.db import models
 from django.utils import timezone
 
@@ -133,3 +134,15 @@ class Rating(models.Model):
 
     class Meta:
         unique_together = ["materi", "user"]
+
+
+class RatingContributor(models.Model):
+    timestamp = models.DateTimeField(auto_now=True)
+    score = models.PositiveIntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)])
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
+
+    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
+        if 1 <= self.score <= 5:
+            super().save(force_insert, force_update, using, update_fields)
+        else:
+            raise ValidationError("Rating score must be integer between 1-5")
\ No newline at end of file
diff --git a/app/templates/app/katalog_kontri.html b/app/templates/app/katalog_kontri.html
index 3ddaf130261abbbb2ccc0c546f855e93b876f14d..7ccaed1d156846d850f12bae96ae1a935295d6f0 100644
--- a/app/templates/app/katalog_kontri.html
+++ b/app/templates/app/katalog_kontri.html
@@ -86,6 +86,8 @@
                         </table>
                     </div>
                 </div>
+            <div class="row"><form method="post">{{ form_rating }} {% csrf_token %}
+                <button type="submit" class="form-control" style="margin-top: 1rem">Submit</button></form> </div>
             </div>
         </header>
 
diff --git a/app/tests.py b/app/tests.py
index adf63c619e866fda2bfc9044834a3dec7961a9d2..5d6b477001e452be1afdb756e04ee6707860c3a2 100644
--- a/app/tests.py
+++ b/app/tests.py
@@ -6,16 +6,15 @@ from django.contrib.auth import get_user_model
 from django.core.exceptions import PermissionDenied, ValidationError
 from django.core.files.uploadedfile import SimpleUploadedFile
 from django.core.management import call_command
-from django.db import IntegrityError
-from django.test import Client, TestCase
+from django.test import Client, TestCase, TransactionTestCase
 from django.urls import resolve
+from django.db.utils import IntegrityError
 
 from administration.models import VerificationSetting, VerificationReport
 from administration.utils import id_generator
-from app.forms import SuntingProfilForm
 from app.views import UploadMateriView, add_rating_materi
 from authentication.models import User
-from .models import Category, Comment, Materi, Like, Rating, ReqMaterial
+from .models import Category, Comment, Materi, Like, Rating, ReqMaterial, RatingContributor
 from .views import (DaftarKatalog, DashboardKontributorView, DetailMateri,
                     ProfilKontributorView, SuksesLoginAdminView,
                     SuksesLoginKontributorView, SuntingProfilView,
@@ -1404,3 +1403,42 @@ class RequestMateriTest(TestCase):
 
         self.assertIn('Missing parameter', response.content.decode())
         self.client.logout()
+
+
+class RatingContributorTest(TransactionTestCase):
+    def setUp(self):
+        self.contributor_credential = {
+            "email": "kontributor@gov.id",
+            "password": id_generator()
+        }
+        self.contributor = get_user_model().objects.create_user(
+            **self.contributor_credential, name="Kontributor", is_contributor=True
+        )
+
+    def test_add_rating_contributor(self):
+        RatingContributor.objects.create(score=3, user=self.contributor)
+        self.assertEqual(1, RatingContributor.objects.count())
+
+    def test_add_rating_contributor_should_failed_when_negative(self):
+        with self.assertRaises(ValidationError):
+            RatingContributor.objects.create(score=-1, user=self.contributor)
+        self.assertEqual(0, RatingContributor.objects.count())
+
+    def test_add_rating_contributor_should_failed_when_bigger_than_five(self):
+        with self.assertRaises(ValidationError):
+            RatingContributor.objects.create(score=6, user=self.contributor)
+        self.assertEqual(0, RatingContributor.objects.count())
+
+    def test_submit_form_correct_rating_contributor_should_added(self):
+        url = f"/profil/{self.contributor.email}/"
+        self.client.post(url, data={"user": self.contributor.id, "score": 5})
+        self.assertEqual(1, RatingContributor.objects.filter(user=self.contributor.id).count())
+        self.client.post(url, data={"user": self.contributor.id, "score": 1})
+        self.assertEqual(2, RatingContributor.objects.filter(user=self.contributor.id).count())
+
+    def test_submit_form_not_correct_rating_contributor_should__not_added(self):
+        url = f"/profil/{self.contributor.email}/"
+        self.client.post(url, data={"user": self.contributor.id, "score": 6})
+        self.assertEqual(0, RatingContributor.objects.filter(user=self.contributor.id).count())
+        self.client.post(url, data={"user": self.contributor.id, "score": 0})
+        self.assertEqual(0, RatingContributor.objects.filter(user=self.contributor.id).count())
diff --git a/app/views.py b/app/views.py
index 8a5ef310d506b74c73c38bfef6000f9e5b7a1302..13e80ff4df9afb0ea7ed572459776f4f49305de7 100644
--- a/app/views.py
+++ b/app/views.py
@@ -9,16 +9,18 @@ from django.core.paginator import Paginator
 from django.db.models import Q, Count
 from django.http import (Http404, HttpResponse, HttpResponseRedirect,
                          JsonResponse)
-from django.shortcuts import get_object_or_404
+from django.shortcuts import get_object_or_404, redirect
 from django.template import loader
 from django.views.generic import TemplateView
 
 from administration.models import VerificationReport
-from app.forms import SuntingProfilForm, UploadMateriForm
-from app.models import Category, Comment, Materi, Like, ViewStatistics, DownloadStatistics, ReqMaterial, Rating
+from app.forms import SuntingProfilForm, UploadMateriForm, RatingContributorForm
+from app.models import Category, Comment, Materi, Like, ViewStatistics, DownloadStatistics, ReqMaterial, Rating, \
+    RatingContributor
 from app.utils.fileManagementUtil import get_random_filename, remove_image_exifdata
 from authentication.models import User
 import django
+from django.contrib import messages
 
 
 class DaftarKatalog(TemplateView):
@@ -95,9 +97,16 @@ class KatalogPerKontributorView(TemplateView):
         page_number = request.GET.get('page')
         materi_list_by_page = paginator.get_page(page_number)
         context["materi_list"] = materi_list_by_page
-
+        contributor = get_object_or_404(User, email=kwargs["email"])
+        context["form_rating"] = RatingContributorForm(initial={'user': contributor})
         return self.render_to_response(context=context)
 
+    def post(self, request, *args, **kwargs):
+        data = RatingContributorForm(request.POST)
+        if data.is_valid():
+            data.save()
+        return redirect('katalog-per-kontributor', email=kwargs['email'])
+
 class DetailMateri(TemplateView):
     template_name = "app/detail_materi.html"