diff --git a/README.md b/README.md
index f5660a894ffe13924442c6e42d60335850084327..1b64c6d4b88fbcfc7c93584b5475ebaf5b2aa118 100644
--- a/README.md
+++ b/README.md
@@ -50,13 +50,17 @@ Le site utilise une base de données SQL. Plusieurs technologies existent mais o
 
 Après avoir installé PostgreSQL, démarrez le serveur en ouvrant pgAdmin, l'interface graphique qui sera installée en même temps que Postgres.
 
+- Créez une nouvelle base de données :
+
+Dans le menu de gauche, dépliez `Servers (1)`, puis votre serveur (nommé `PostgreSQL XX` par défaut), puis faites un clic droit sur l'onglet `Databases` et créez une base de données nommée `oser_backend_db`.
+
 ### Installation du projet
 
-- (Recommandé) Créez un environnement virtuel (ici appelé `env`) puis activez-le :
+- (Recommandé) Créez un environnement virtuel (appelé ici oser-back) à l'aide de conda et activez-le :
 
 ```bash
-$ python -m venv env
-$ source env/bin/activate
+$ conda create -n oser-back
+$ conda activate oser-back
 ```
 
 - Installez les dépendances :
@@ -70,6 +74,7 @@ $ pip install -r requirements.txt
 ```bash
 $ python manage.py migrate
 ```
+(En cas d'erreur, les logs du serveur PostgreSQL sont disponibles dans : %PROGRAMFILES%\PostgreSQL\POSTGRESQL_VERSION_NUM\data\log)
 
 Il ne vous reste plus qu'à lancer le serveur de développement :
 
diff --git a/api/urls.py b/api/urls.py
index dbd3f62fe5ce8ba2ed67d64dca500e2b15060aee..46497be11fa1b6e898d2887dd91eaf1fe3c6933d 100644
--- a/api/urls.py
+++ b/api/urls.py
@@ -26,7 +26,7 @@ router.register('users', users_views.UserViewSet)
 
 # Profiles views
 router.register('tutors', profiles_views.TutorViewSet)
-router.register('students', profiles_views.StudentViewSet)
+router.register('students', profiles_views.StudentViewSet, base_name='student')
 
 # Register views
 router.register('registrations', register_views.RegistrationViewSet)
diff --git a/core/factory.py b/core/factory.py
index a812eedf66da680b44e704315bd4a2fc0f7810f6..7167327d48510efeb20e2ae1e70c981bee7fb623 100644
--- a/core/factory.py
+++ b/core/factory.py
@@ -5,7 +5,7 @@ import factory.django
 from . import models
 
 
-class DocumentFactory(factory.DjangoModelFactory):
+class DocumentFactory(factory.django.DjangoModelFactory):
     """Document object factory."""
 
     class Meta:  # noqa
@@ -15,7 +15,7 @@ class DocumentFactory(factory.DjangoModelFactory):
     content = factory.Faker('text', max_nb_chars=1000, locale='fr')
 
 
-class AddressFactory(factory.DjangoModelFactory):
+class AddressFactory(factory.django.DjangoModelFactory):
     """Address object factory."""
 
     class Meta:  # noqa
diff --git a/oser_backend/settings/common.py b/oser_backend/settings/common.py
index eca12ccb0e7dec521a6210f1c99faf53228ac2f5..9579af4b53b12213685b37613ac01aa7bdc42a30 100644
--- a/oser_backend/settings/common.py
+++ b/oser_backend/settings/common.py
@@ -38,7 +38,7 @@ DJANGO_APPS = [
     'whitenoise.runserver_nostatic',
     'django.contrib.staticfiles',
     'django.forms',
-    'django.contrib.sites',
+    'django.contrib.sites'
 ]
 
 THIRD_PARTY_APPS = [
@@ -236,7 +236,7 @@ LOGGING = {
 # Connect custom PasswordResetSerializer to override default
 
 REST_AUTH_SERIALIZERS = {
-    'PASSWORD_RESET_SERIALIZER': 
+    'PASSWORD_RESET_SERIALIZER':
         'oser_backend.serializers.PasswordResetSerializer',
 }
 
@@ -246,7 +246,7 @@ DEFAULT_FROM_EMAIL = "admin@oser-cs.fr"
 EMAIL_BACKEND = 'sendgrid_backend.SendgridBackend'
 SENDGRID_API_KEY = os.getenv('SENDGRID_API_KEY')
 
-# Sendgrid configuration 
+# Sendgrid configuration
 
 EMAIL_HOST = 'smtp.sendgrid.net'
 EMAIL_HOST_USER = 'apikey'
diff --git a/profiles/admin.py b/profiles/admin.py
index 4f00aa12ef96c41e9b9b99522ef931d97c651dec..63f6e66fc0b79134d7aed59b5cd05e2418bcf5ff 100644
--- a/profiles/admin.py
+++ b/profiles/admin.py
@@ -43,7 +43,7 @@ class TutorAdmin(ProfileAdminMixin, admin.ModelAdmin,ExportCsvMixin):
 @admin.register(Student)
 class StudentAdmin(ProfileAdminMixin, admin.ModelAdmin,ExportCsvMixin):
     """Student admin panel."""
-
+    list_filter = ('school', 'year')
     class Meta:  # noqa
         model = Student
     actions = ["export_as_csv"]
\ No newline at end of file
diff --git a/profiles/factory.py b/profiles/factory.py
index 886b5dde680d2945e4fbc1b30455990a390fa491..6b8b4ff6b212ccb5c6c58d0c47b62cf855a09b0c 100644
--- a/profiles/factory.py
+++ b/profiles/factory.py
@@ -12,7 +12,7 @@ from users.factory import UserFactory
 from . import models
 
 
-class StudentFactory(factory.DjangoModelFactory):
+class StudentFactory(factory.django.DjangoModelFactory):
     """Student object factory."""
 
     class Meta:  # noqa
@@ -24,7 +24,7 @@ class StudentFactory(factory.DjangoModelFactory):
 _this_year = datetime.today().year
 
 
-class TutorFactory(factory.DjangoModelFactory):
+class TutorFactory(factory.django.DjangoModelFactory):
     """Tutor object factory."""
 
     class Meta:  # noqa
diff --git a/profiles/migrations/0003_auto_20200914_0057.py b/profiles/migrations/0003_auto_20200914_0057.py
new file mode 100644
index 0000000000000000000000000000000000000000..ebe33bdb9876e88f5967032f96c1bf3adc9f4bbb
--- /dev/null
+++ b/profiles/migrations/0003_auto_20200914_0057.py
@@ -0,0 +1,88 @@
+# Generated by Django 2.2 on 2020-09-13 22:57
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('profiles', '0002_auto_20180911_1938'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='student',
+            name='addressNumber',
+            field=models.IntegerField(blank=True, null=True, verbose_name='numéro de rue'),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='city',
+            field=models.CharField(blank=True, max_length=50, null=True, verbose_name='nom de ville'),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='dependantsNumber',
+            field=models.CharField(blank=True, max_length=12, null=True, verbose_name="numero d'urgence"),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='fatherActivity',
+            field=models.CharField(blank=True, max_length=70, null=True, verbose_name='metier du pere'),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='gender',
+            field=models.CharField(blank=True, max_length=20, null=True, verbose_name='genre'),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='grade',
+            field=models.CharField(blank=True, max_length=20, null=True, verbose_name='nom du niveau de la classe'),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='motherActivity',
+            field=models.CharField(blank=True, max_length=70, null=True, verbose_name='metier de la mere'),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='parentsEmail',
+            field=models.EmailField(blank=True, max_length=20, null=True, verbose_name='adresse mail parentale'),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='parentsPhone',
+            field=models.CharField(blank=True, max_length=12, null=True, verbose_name='numéro de téléphone parental'),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='parentsStatus',
+            field=models.CharField(blank=True, max_length=30, null=True, verbose_name='statut des parents'),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='personnalPhone',
+            field=models.CharField(blank=True, max_length=12, null=True, verbose_name='numéro de téléphone personnel'),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='scholarship',
+            field=models.BooleanField(blank=True, null=True, verbose_name='boursier'),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='school',
+            field=models.CharField(blank=True, max_length=70, null=True, verbose_name="nom de l'ecole"),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='street',
+            field=models.CharField(blank=True, max_length=70, null=True, verbose_name='nom de rue'),
+        ),
+        migrations.AlterField(
+            model_name='tutor',
+            name='promotion',
+            field=models.IntegerField(choices=[(2023, '2023'), (2022, '2022'), (2021, '2021'), (2020, '2020'), (2019, '2019')], default=2023),
+        ),
+    ]
diff --git a/profiles/migrations/0004_auto_20200915_1827.py b/profiles/migrations/0004_auto_20200915_1827.py
new file mode 100644
index 0000000000000000000000000000000000000000..d94b486a824cbe4d55b98228c8065bb28520bf80
--- /dev/null
+++ b/profiles/migrations/0004_auto_20200915_1827.py
@@ -0,0 +1,43 @@
+# Generated by Django 2.2 on 2020-09-15 16:27
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('profiles', '0003_auto_20200914_0057'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='student',
+            name='dependantsNumber',
+            field=models.CharField(blank=True, max_length=12, null=True, verbose_name="numéro d'urgence"),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='fatherActivity',
+            field=models.CharField(blank=True, max_length=70, null=True, verbose_name='métier du père'),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='grade',
+            field=models.CharField(blank=True, max_length=20, null=True, verbose_name='niveau de la classe'),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='motherActivity',
+            field=models.CharField(blank=True, max_length=70, null=True, verbose_name='métier de la mère'),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='scholarship',
+            field=models.NullBooleanField(verbose_name='boursier'),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='school',
+            field=models.CharField(blank=True, max_length=70, null=True, verbose_name="nom de l'école"),
+        ),
+    ]
diff --git a/profiles/migrations/0004_auto_20200918_1320.py b/profiles/migrations/0004_auto_20200918_1320.py
new file mode 100644
index 0000000000000000000000000000000000000000..0b1e26b5ff27618b90b05d48a5b4959b5c196d05
--- /dev/null
+++ b/profiles/migrations/0004_auto_20200918_1320.py
@@ -0,0 +1,43 @@
+# Generated by Django 2.2 on 2020-09-18 11:20
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('profiles', '0003_auto_20200914_0057'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='student',
+            name='dependantsNumber',
+            field=models.CharField(blank=True, max_length=12, null=True, verbose_name="numéro d'urgence"),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='fatherActivity',
+            field=models.CharField(blank=True, max_length=70, null=True, verbose_name='métier du père'),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='grade',
+            field=models.CharField(blank=True, max_length=20, null=True, verbose_name='niveau de la classe'),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='motherActivity',
+            field=models.CharField(blank=True, max_length=70, null=True, verbose_name='métier de la mère'),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='scholarship',
+            field=models.NullBooleanField(verbose_name='boursier'),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='school',
+            field=models.CharField(blank=True, max_length=70, null=True, verbose_name="nom de l'école"),
+        ),
+    ]
diff --git a/profiles/migrations/0005_auto_20200918_1805.py b/profiles/migrations/0005_auto_20200918_1805.py
new file mode 100644
index 0000000000000000000000000000000000000000..7e5756b35f30031a1461c9e722ade5bd3c0d56b9
--- /dev/null
+++ b/profiles/migrations/0005_auto_20200918_1805.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2 on 2020-09-18 16:05
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('profiles', '0004_auto_20200918_1320'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='student',
+            name='scholarship',
+            field=models.CharField(blank=True, max_length=10, null=True, verbose_name='boursier'),
+        ),
+    ]
diff --git a/profiles/migrations/0006_auto_20200918_1818.py b/profiles/migrations/0006_auto_20200918_1818.py
new file mode 100644
index 0000000000000000000000000000000000000000..a1d92c84cb5637c04014142e8f0eb6a0ce7047ee
--- /dev/null
+++ b/profiles/migrations/0006_auto_20200918_1818.py
@@ -0,0 +1,28 @@
+# Generated by Django 2.2 on 2020-09-18 16:18
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('profiles', '0005_auto_20200918_1805'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='student',
+            name='nationality',
+            field=models.CharField(blank=True, max_length=30, null=True, verbose_name='nationalité'),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='specialTeaching',
+            field=models.CharField(blank=True, max_length=30, null=True, verbose_name='enseignement de spécialité'),
+        ),
+        migrations.AddField(
+            model_name='student',
+            name='zipCode',
+            field=models.CharField(blank=True, max_length=10, null=True, verbose_name='code postal'),
+        ),
+    ]
diff --git a/profiles/migrations/0007_merge_20200918_1824.py b/profiles/migrations/0007_merge_20200918_1824.py
new file mode 100644
index 0000000000000000000000000000000000000000..ff45a3495fcaffea7b785342967fdf43431f60e6
--- /dev/null
+++ b/profiles/migrations/0007_merge_20200918_1824.py
@@ -0,0 +1,14 @@
+# Generated by Django 2.2 on 2020-09-18 16:24
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('profiles', '0006_auto_20200918_1818'),
+        ('profiles', '0004_auto_20200915_1827'),
+    ]
+
+    operations = [
+    ]
diff --git a/profiles/migrations/0008_auto_20200918_1913.py b/profiles/migrations/0008_auto_20200918_1913.py
new file mode 100644
index 0000000000000000000000000000000000000000..cdf1810b92ba16c81f69a0c1d03524b70671e8a3
--- /dev/null
+++ b/profiles/migrations/0008_auto_20200918_1913.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2 on 2020-09-18 17:13
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('profiles', '0007_merge_20200918_1824'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='student',
+            name='scholarship',
+            field=models.CharField(blank=True, max_length=10, null=True, verbose_name='boursier'),
+        ),
+    ]
diff --git a/profiles/migrations/0009_auto_20200923_1329.py b/profiles/migrations/0009_auto_20200923_1329.py
new file mode 100644
index 0000000000000000000000000000000000000000..5dc6c13dc8941b3a97754791132d8f584da47eb8
--- /dev/null
+++ b/profiles/migrations/0009_auto_20200923_1329.py
@@ -0,0 +1,43 @@
+# Generated by Django 2.2 on 2020-09-23 11:29
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('profiles', '0008_auto_20200918_1913'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='student',
+            name='dependantsNumber',
+            field=models.IntegerField(blank=True, null=True, verbose_name='nombre de personnes à charge'),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='nationality',
+            field=models.CharField(blank=True, max_length=50, null=True, verbose_name='nationalité'),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='parentsEmail',
+            field=models.EmailField(blank=True, max_length=70, null=True, verbose_name='adresse mail parentale'),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='parentsStatus',
+            field=models.CharField(blank=True, max_length=70, null=True, verbose_name='statut des parents'),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='scholarship',
+            field=models.CharField(blank=True, max_length=50, null=True, verbose_name='boursier'),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='specialTeaching',
+            field=models.CharField(blank=True, max_length=50, null=True, verbose_name='enseignement de spécialité'),
+        ),
+    ]
diff --git a/profiles/migrations/0010_auto_20200923_1444.py b/profiles/migrations/0010_auto_20200923_1444.py
new file mode 100644
index 0000000000000000000000000000000000000000..fd5da54118b9f0ff8ba3e85af509d8cf7ac87a14
--- /dev/null
+++ b/profiles/migrations/0010_auto_20200923_1444.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2 on 2020-09-23 12:44
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('profiles', '0009_auto_20200923_1329'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='student',
+            old_name='personnalPhone',
+            new_name='personalPhone',
+        ),
+    ]
diff --git a/profiles/migrations/0011_student_classtype.py b/profiles/migrations/0011_student_classtype.py
new file mode 100644
index 0000000000000000000000000000000000000000..04821189e139d63ba4fcb74c6986fb7b0e67b3af
--- /dev/null
+++ b/profiles/migrations/0011_student_classtype.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2 on 2020-09-24 16:56
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('profiles', '0010_auto_20200923_1444'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='student',
+            name='classType',
+            field=models.CharField(blank=True, max_length=50, null=True, verbose_name='général/techno'),
+        ),
+    ]
diff --git a/profiles/migrations/0012_student_year.py b/profiles/migrations/0012_student_year.py
new file mode 100644
index 0000000000000000000000000000000000000000..359b6cbd51b920471e2203e942a3805120f98cc2
--- /dev/null
+++ b/profiles/migrations/0012_student_year.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2 on 2020-09-25 12:14
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('profiles', '0011_student_classtype'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='student',
+            name='year',
+            field=models.CharField(blank=True, max_length=10, null=True, verbose_name='année'),
+        ),
+    ]
diff --git a/profiles/models.py b/profiles/models.py
index 28061fa97817f7fd8dd4c0a58ad90d3e8da141bd..675354d84013b7b40bd59c2f9d418330531e9c6a 100644
--- a/profiles/models.py
+++ b/profiles/models.py
@@ -4,7 +4,7 @@ from django.db import models
 from django.shortcuts import reverse
 from dry_rest_permissions.generics import authenticated_users
 from .utils import get_promotion_range
-
+from datetime import datetime
 
 class ProfileMixin:
     """Mixin with common functionnality for profiles."""
@@ -52,6 +52,144 @@ class Student(ProfileMixin, models.Model):
         related_name='student',
     )
 
+    classType = models.CharField(max_length=50,
+        null=True,
+        blank=True,
+        verbose_name="général/techno",
+    )
+
+    nationality = models.CharField(max_length=50,
+        null=True,
+        blank=True,
+        verbose_name="nationalité",
+    )
+
+    specialTeaching = models.CharField(max_length=50,
+        null=True,
+        blank=True,
+        verbose_name="enseignement de spécialité",
+    )
+
+    zipCode = models.CharField(max_length=10,
+        null=True,
+        blank=True,
+        verbose_name="code postal",
+    )
+
+
+    gender = models.CharField(max_length=20,
+        null=True,
+        blank=True,
+        verbose_name="genre",
+    )
+
+    addressNumber = models.IntegerField(
+        null=True,
+        blank=True,
+        verbose_name="numéro de rue"
+    )
+
+    street = models.CharField(max_length=70,
+        null=True,
+        blank=True,
+        verbose_name="nom de rue"
+    )
+
+    city = models.CharField(max_length=50,
+        null=True,
+        blank=True,
+        verbose_name="nom de ville"
+    )
+
+    personalPhone = models.CharField(max_length=12,
+        null=True,
+        blank=True,
+        verbose_name="numéro de téléphone personnel"
+    )
+
+    parentsPhone = models.CharField(max_length=12,
+        null=True,
+        blank=True,
+        verbose_name="numéro de téléphone parental"
+    )
+
+    parentsEmail = models.EmailField(max_length=70,
+        null=True,
+        blank=True,
+        verbose_name="adresse mail parentale"
+    )
+
+
+    school = models.CharField(max_length=70,
+        null=True,
+        blank=True,
+        verbose_name="établissement"
+    )
+
+
+    grade = models.CharField(max_length=20,
+        null=True,
+        blank=True,
+        verbose_name="niveau de la classe"
+    )
+
+
+    scholarship = models.CharField(max_length=50,
+        null=True,
+        blank=True,
+        verbose_name="boursier"
+    )
+
+
+    fatherActivity = models.CharField(max_length=70,
+        null=True,
+        blank=True,
+        verbose_name="métier du père"
+    )
+
+
+    motherActivity = models.CharField(max_length=70,
+        null=True,
+        blank=True,
+        verbose_name="métier de la mère"
+    )
+
+
+    parentsStatus = models.CharField(max_length=70,
+        null=True,
+        blank=True,
+        verbose_name="statut des parents"
+    )
+
+
+    dependantsNumber = models.IntegerField(
+        null=True,
+        blank=True,
+        verbose_name="nombre de personnes à charge"
+    )
+
+    year = models.CharField(max_length=10,
+        null=True,
+        blank=True,
+        verbose_name="année"
+    )
+
+    @staticmethod
+    def has_write_permission(request):
+        return True
+
+    def has_object_write_permission(self, request):
+        return request.user == self.user
+
+    def save(self, *args, **kwargs):
+        """Updates the year field based on the last modified date"""
+        date_now = datetime.now()
+        if date_now.month>=9:
+            self.year = f"{date_now.year}/{date_now.year+1}"
+        else:
+            self.year = f"{date_now.year-1}/{date_now.year}"
+        return super(Student,self).save(*args, **kwargs)
+
     class Meta:  # noqa
         verbose_name = 'lycéen'
 
diff --git a/profiles/serializers.py b/profiles/serializers.py
index 31b20310d293647aacde450dca91509f8af66088..778dc21ff9563ca1a6e9b848915ae409146112ab 100644
--- a/profiles/serializers.py
+++ b/profiles/serializers.py
@@ -31,11 +31,11 @@ class StudentSerializer(serializers.HyperlinkedModelSerializer):
         read_only=True)
     registration = StudentRegistrationSerializer()
 
+
     class Meta:  # noqa
         model = Student
         fields = (
-            'user_id', 'user', 'registration', 'visits', 'url',
-        )
+            'user_id', 'user', 'url', 'registration', 'visits', 'gender', 'addressNumber', 'street', 'city', 'personalPhone', 'parentsPhone', 'parentsEmail', 'school', 'grade', 'scholarship', 'fatherActivity', 'motherActivity', 'parentsStatus', 'dependantsNumber', 'specialTeaching', 'nationality', 'zipCode', 'classType')
         extra_kwargs = {
             'url': {'view_name': 'api:student-detail'},
         }
diff --git a/profiles/views.py b/profiles/views.py
index 0c157ef80761cfde6b830d6820eae66d48ab365b..b81ec2cdb13554e7f45e37f7b4736f1a9a0c5d85 100644
--- a/profiles/views.py
+++ b/profiles/views.py
@@ -5,6 +5,7 @@ from dry_rest_permissions.generics import DRYPermissions
 from rest_framework import viewsets
 from rest_framework.decorators import action
 from rest_framework.response import Response
+from django_filters.rest_framework import DjangoFilterBackend
 
 from visits.serializers import VisitSerializer
 
@@ -23,40 +24,21 @@ class TutorViewSet(viewsets.ReadOnlyModelViewSet):
     permission_classes = (DRYPermissions,)
 
 
-class StudentViewSet(viewsets.ReadOnlyModelViewSet):
-    """API endpoint that allows students to be viewed.
+class StudentViewSet(viewsets.ModelViewSet):
+    """API endpoint that allows students to be viewed, and profiles to be updated."""
 
-    list:
+    def get_serializer(self, *args, **kwargs):
+            kwargs['partial'] = True
+            return super(StudentViewSet, self).get_serializer(*args, **kwargs)
 
-    ### Example response
+    def get_queryset(self):
+        user = self.request.user
+        if user.is_staff:
+            return Student.objects.all()
+        else:
+            return Student.objects.filter(user_id = user.id)
 
-    List of results from `retrieve` (see the example response for `retrieve`).
 
-    retrieve:
-
-    ### Example response
-
-        {
-            "user_id": 4,
-            "user": {
-                "id": 4,
-                "email": "charles.dumont@example.net",
-                "profile_type": null,
-                "first_name": "",
-                "last_name": "",
-                "url": "http://localhost:8000/api/users/4/"
-            },
-            "registration": {
-                "id": 3,
-                "submitted": "2018-05-05T14:15:10.998206+02:00",
-                "validated": false
-            },
-            "visits": [],
-            "url": "http://localhost:8000/api/students/2/"
-        }
-    """
-
-    queryset = Student.objects.all()
     serializer_class = StudentSerializer
     permission_classes = (DRYPermissions,)
 
diff --git a/projects/factory.py b/projects/factory.py
index f826ab8d36261eb8a99acd51cdcfb2a725f1fcfb..8a539812d5abff29ff8657c0a36a9292e4789920 100644
--- a/projects/factory.py
+++ b/projects/factory.py
@@ -7,7 +7,7 @@ from users.factory import UserFactory
 from .models import Project, Edition, Participation, EditionForm
 
 
-class ProjectFactory(factory.DjangoModelFactory):
+class ProjectFactory(factory.django.DjangoModelFactory):
     """Project object factory."""
 
     class Meta:  # noqa
@@ -20,7 +20,7 @@ class ProjectFactory(factory.DjangoModelFactory):
     logo = factory.django.ImageField(color='green')
 
 
-class EditionFactory(factory.DjangoModelFactory):
+class EditionFactory(factory.django.DjangoModelFactory):
     """Edition object factory."""
 
     class Meta:  # noqa
@@ -37,7 +37,7 @@ class EditionFactory(factory.DjangoModelFactory):
         return project and project or ProjectFactory.create()
 
 
-class EditionFormFactory(factory.DjangoModelFactory):
+class EditionFormFactory(factory.django.DjangoModelFactory):
 
     class Meta:  # noqa
         model = EditionForm
@@ -45,7 +45,7 @@ class EditionFormFactory(factory.DjangoModelFactory):
     deadline = factory.Faker('future_date')
 
 
-class ParticipationFactory(factory.DjangoModelFactory):
+class ParticipationFactory(factory.django.DjangoModelFactory):
     """Participation object factory."""
 
     class Meta:  # noqa
diff --git a/register/factory.py b/register/factory.py
index 973d6e793e7b4abeef18708936f0b0eeef3b44fd..4fe95805b716f63146d51b8b76e76fb3c99a3fcd 100644
--- a/register/factory.py
+++ b/register/factory.py
@@ -8,7 +8,7 @@ from utils import printable_only
 from . import models
 
 
-class RegistrationFactory(factory.DjangoModelFactory):
+class RegistrationFactory(factory.django.DjangoModelFactory):
     """Registration object factory."""
 
     class Meta:  # noqa
diff --git a/test b/test
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/tests/test_profiles/test_student.py b/tests/test_profiles/test_student.py
index 0d9d65fc47e1619475c78325b8eb82f4af3641b2..f5b6541951f94976be5db30cde8b0fe1b8f7f402 100644
--- a/tests/test_profiles/test_student.py
+++ b/tests/test_profiles/test_student.py
@@ -3,7 +3,7 @@
 from profiles.factory import StudentFactory
 from profiles.models import Student
 from tests.utils import ModelTestCase
-from users.factory import UserFactory
+from users.factory import UserFactory, StaffUserFactory
 
 
 class StudentTestCase(ModelTestCase):
@@ -32,7 +32,8 @@ class StudentTestCase(ModelTestCase):
         self.assertEqual(self.obj, self.obj.user.student)
 
     def test_get_absolute_url(self):
-        self.client.force_login(UserFactory.create())
+        staff_user = StaffUserFactory.create()
+        self.client.force_login(staff_user)
         url = self.obj.get_absolute_url()
         response = self.client.get(url)
         self.assertEqual(200, response.status_code)
diff --git a/tests/test_profiles/test_student_api.py b/tests/test_profiles/test_student_api.py
index 204649b47eadba66ce7be8a9e17c09568244d664..d9caacb0d140e89e4d3724b35fcc0780647d2e74 100644
--- a/tests/test_profiles/test_student_api.py
+++ b/tests/test_profiles/test_student_api.py
@@ -19,7 +19,7 @@ class StudentEndpointsTest(HyperlinkedAPITestCase):
     def perform_retrieve(self, obj=None):
         if obj is None:
             obj = self.factory.create()
-        response = self.client.get('/api/students/{obj.pk}/'.format(obj=obj))
+        response = self.client.get('/api/students/')
         return response
 
     def test_list(self):
diff --git a/users/factory.py b/users/factory.py
index b197e55f088bb9b1901794aaad9f16272576836c..850d0c4b7a167af11e3dfc7d016e85a79218ea98 100644
--- a/users/factory.py
+++ b/users/factory.py
@@ -9,7 +9,7 @@ from utils import printable_only
 User = get_user_model()
 
 
-class UserFactory(factory.DjangoModelFactory):
+class UserFactory(factory.django.DjangoModelFactory):
     """User object factory."""
 
     class Meta:  # noqa
@@ -41,3 +41,7 @@ class UserFactory(factory.DjangoModelFactory):
         manager = cls._get_manager(model_class)
         # The default would use ``manager.create(*args, **kwargs)``
         return manager.create_user(*args, **kwargs)
+
+class StaffUserFactory(UserFactory):
+    """Staff user object factory."""
+    is_staff = True
\ No newline at end of file
diff --git a/visits/factory.py b/visits/factory.py
index 11817aa2c4692fcf5483f3029886a64cb5b9eae3..05fce07d0a39d1fcd1d5257c7a68390876e28f30 100644
--- a/visits/factory.py
+++ b/visits/factory.py
@@ -15,7 +15,7 @@ from . import models
 User = get_user_model()
 
 
-class PlaceFactory(factory.DjangoModelFactory):
+class PlaceFactory(factory.django.DjangoModelFactory):
     """Place object factory."""
 
     class Meta:  # noqa
@@ -28,7 +28,7 @@ class PlaceFactory(factory.DjangoModelFactory):
     description = factory.LazyAttribute(lambda o: '\n'.join(o._description))
 
 
-class VisitFactory(factory.DjangoModelFactory):
+class VisitFactory(factory.django.DjangoModelFactory):
     """Visit object factory."""
 
     deadline_random_range = (-5, -1)
@@ -81,7 +81,7 @@ class VisitWithClosedRegistrationsFactory(VisitFactory):
     deadline_random_range = (-10, -6)  # guaranteed to be before today
 
 
-class ParticipationFactory(factory.DjangoModelFactory):
+class ParticipationFactory(factory.django.DjangoModelFactory):
     """Visit participant object factory.
 
     Users and visit are picked from pre-existing objects,