Bonjour à tous,
Je viens vers vous car actuellement je travaille sur un projet personnel en django et je souhaiterais mettre en place le système d'authentification de django. J'ai lu différents tutoriels et aussi la documentation de django sur le sujet et j'ai vu qu'il y avait énormément de possibilités. Mon but serait de réaliser un système d'authentification pour plusieurs types d'utilisateur avec authentification par email et non username. Je me suis donc tourné vers la classe AbtractBaseUser de django.
Cependant,
je ne sais pas encore quel est le choix le plus judicieux afin de définir mon système d'authentification.
Pour le moment, j'ai réalisé un système de la manière suivante :
models.py
Code python : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84 from django.db import models from django.conf import settings from django.utils.translation import ugettext_lazy as _ from django.contrib.auth.models import ( BaseUserManager, AbstractBaseUser ) TYPE_USER = ( ('student', _('Student')), ('employee', _('Employee')), ) class MyuserManager(BaseUserManager): def create_user(self, email, last_name, first_name, date_of_birth, user_type, password=None): if not email: raise ValueError("users must have an email address") user = self.model( email = self.normalize_email(email), last_name = last_name, first_name = first_name, date_of_birth = date_of_birth, user_type = user_type, ) user.set_password(password) user.save() #default database(can use 'using=' attribute to select db return user def create_superuser(self, email, password, last_name, first_name, date_of_birth, user_type): user = self.create_user(email, password = password, date_of_birth = date_of_birth, last_name = last_name, first_name = first_name, user_type = user_type, ) user.is_admin = True user.is_staff = True user.save() return user class MyUser(AbstractBaseUser): """Based model user""" email = models.EmailField( verbose_name = 'email', max_length=255, unique=True, ) last_name = models.CharField(max_length=30) first_name = models.CharField(max_length=30) date_of_birth = models.DateField() user_type = models.CharField(_('Type'), choices=TYPE_USER, max_length=20, default='student') phone = models.CharField(max_length=20, blank=True) friends = models.ManyToManyField("self", blank=True) faculty = models.ForeignKey(Faculty, null=True, blank=True) desk = models.CharField(max_length=30, blank=True) campus = models.ForeignKey(Campus, null=True, blank=True) job = models.ForeignKey(Function, null=True, blank=True) cursus = models.ForeignKey(Cursus, null=True, blank=True) year = models.IntegerField(null=True, blank=True) is_active = models.BooleanField(default=True) is_admin = models.BooleanField(default=False) is_staff = models.BooleanField(default=False) objects = MyuserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['last_name', 'first_name', 'date_of_birth', 'user_type'] def get_full_name(self): return self.email def get_short_name(self): return self.email def __str__(self): return self.email def has_perm(self, perm, obj=None): return True def has_module_perms(self, app_label): return True
Pour ce modèle, ce que j'ai fait c'est regrouper tous les champs dont j'aurai besoin pour mes utilisateurs ainsi je n'ai qu'un seul modèle dans ma base et avec l'attribut user_type je peux définir mon type d'utilisateur.
Ici je ne sais pas si cela est la meilleur solution car j'ai vu qu'il était possible d'utiliser l'héritage ou encore l'utilisation de clé étrangère.
Ainsi mes autres solutions seraient
soit je définis un modèle comme ceci :
Code python : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 class MyUser(abstractBaseUser): #Ici les champs commun à tous les utilisateurs class MyStudentUser(MyUser): #ici les champs spécifiques à l'étudiant class MyEmployeeUser(MyUser): #ici les champs spécifiques à l'employée
ou alors comme cela:
Code python : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 class MyUser(abstractBaseUser): #Ici les champs commun à tous les utilisateurs class MyStudentUser(models.Model): user = models.ForeignKey(MyUser, unique=True) (Ou bien un OneToOneField) #ici les champs spécifiques à l'étudiant class MyEmployeeUser(models.Model): user = models.ForeignKey(MyUser, unique=True) #ici les champs spécifiques à l'employée
Avec mon unique modèle, j'ai essayé de créer une vue qui permettrait à un utilisateur de se créer un profile comme ceci:
views.py
Code python : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 class RegisterProfile(CreateView): model = MyUser template_name = 'fbLike/user_profile.html' form_class = StudentProfileForm second_form_class = EmployeeProfileForm def get_success_url(self): return reverse('login',) def get_context_data(self, **kwargs): context = super(RegisterProfile, self).get_context_data(**kwargs) if 'studenForm' not in context: context['studentForm'] = self.form_class if 'employeeForm' not in context: context['employeeForm'] = self.second_form_class return context def post(self, request, *args, **kwargs): if request.POST['profileType'] == 'student': studentForm = self.form_class(request.POST) employeeForm = self.second_form_class() studentForm.user_type = 'student' if studentForm.is_valid(): newStudentUser = MyUser() newStudentUser.set_password(studentForm.cleaned_data['password']) newStudentUser.email = studentForm.cleaned_data['email'] newStudentUser.first_name = studentForm.cleaned_data['first_name'] newStudentUser.last_name = studentForm.cleaned_data['last_name'] newStudentUser.date_of_birth = studentForm.cleaned_data['date_of_birth'] newStudentUser.save() return redirect('login') else: employeeForm = self.second_form_class(request.POST) studentForm = self.form_class() employeeForm.user_type = 'employee' if employeeForm.is_valid(): newEmployeeUser = MyUser() newEmployeeUser.set_password(employeeForm.cleaned_data['password']) newEmployeeUser.email = employeeForm.cleaned_data['email'] newEmployeeUser.first_name = employeeForm.cleaned_data['first_name'] newEmployeeUser.last_name = employeeForm.cleaned_data['last_name'] newEmployeeUser.date_of_birth = employeeForm.cleaned_data['date_of_birth'] newEmployeeUser.save() return redirect('login') return render(request, self.template_name, {'studentForm': studentForm, 'employeeForm': employeeForm})
N'étant pas encore à l'aise avec django, je ne sais pas si c'est une solution acceptable. D'autant plus qu'ici j'ai déjà un petit problème lors de la création en soumettant mon formulaire avec les champs remplis. Je me retrouve avec une erreur de champs obligatoires alors qu'ils sont remplis.
Ensuite, j'ai essayé de mettre en place les modèles utilisants la foreign key mais je ne vois pas comment faire pour créer la vue de création d'utilisateur, notamment comment afficher les champs de la foreign key dans mon formulaire de l'étudiant ou de l'employée. dois-je créer un utilisateur MyUser avant puis l'ajouter à mes autres models où bien est-il possible de le faire en même temps que dans le formulaire de l'étudiant ou de l'employée ?
Au vue de ce long récit, j'espère ne pas être trop vague dans mon propos. Et que cela correspond bien aux régles du forum (je suis nouveau).
Enfin, auriez-vous des conseils à me donner ou des pistes vers ou chercher afin de que je puisse comprendre comme marche le système.
Je vous remercie d'avance.
Partager