Votre navigateur n'est pas à jour !

Merci de mettre à jour votre navigateur pour utiliser mon blog. Mettre à jour mon navigateur maintenant

×

Django - Créer une authentification sur le système interne de django

Date de publication 25 nov. 2012
Django embarque un système d'authentification et nous allons voir comment se reposer sur ce système.  

1) Création du routage



Il faut éditer le fichier urls.py de votre application pour indiquer à Django de suivre :
- tous les liens vers le sytème d'authentification propre à django pour demander une authentification sur les urls
- le lien /login vers le sytème d'authentification propre à django pour la connexion
- le lien /logout vers le sytème d'authentification propre à django pour la déconnexion
- le lien /join vers la vérification du formulaire après une demande d'inscription
- le lien /dashboard vers la vue une fois que l'authentification a réussi

L'ordre de routage est executé dans l'ordre de déclaration.

from django.conf.urls.defaults import *
from django.contrib.auth.decorators import login_required
from django.views.generic.simple import direct_to_template

urlpatterns = patterns('',
        (r'^$' , login_required(direct_to_template, redirect_field_name=''),{'template':'registration/login.html' }),
        (r'^login$', 'django.contrib.auth.views.login'),
        (r'^logout$', 'django.contrib.auth.views.logout', {'next_page': '/'}),
        (r'^join$', 'engine.views.join'),
        (r'^dashboard$', 'engine.views.dashboard'),
 )



Le template de connexion par défaut est stocké dans registration/login.html, mais vous pouvez spécifier un autre fichier.
Je redéfini le redirect_field_name car par défaut dans l'url un paramètre GET next est inséré. Dans ma définition je ne place pas de paramètre GET.
Pour la déconnexion, je spécifie une redirection vers / après cette déconnexion.
Il faut aussi définir des variables dans le fichiers settings.py, elles sont nécessaire pour login_required()

LOGIN_URL = '/login' # Lien vers la page si l'authentification échoue
LOGIN_REDIRECT_URL = '/dashboard' # Lien vers la page si l'authentification réussi


Par défaut le LOGIN_URL pointe sur le lien /accounts/login
Voilà un exemple du template de registration/login.html

{% extends "base.html" %}
{% block content %}
{% if form.errors %}
        <p>La connexion a échoué...</p>
{% endif %}
        <form method="post" action="{% url django.contrib.auth.views.login %}">
        {% csrf_token %}
        <table>
                <tr>
                         <td>{{ form.username.label_tag }}</td>
                         <td>{{ form.username }}</td>
                </tr>
                <tr>
                         <td>{{ form.password.label_tag }}</td>
                         <td>{{ form.password }}</td>
                </tr>
        </table>
        <input type="submit" value="login" />
        <input type="hidden" name="next" value="{{ next }}" />
        </form>
{% endblock %}

Nous venons de créer le système d'authentification, maintenant nous allons voir comment créer le système de création d'un utilisateur

2) Création d'un utilisateur


Django possède son propre système de gestion des utilisateurs, notamment utilisé pour la connexion sur la partie admin de Django.
Nous allons étendre cette fonctionnalité pour ajouter d'autres informations sur cet utilisateur (pour l'exemple cela correspond à l'id_version
Cela se nomme un profile sous django.
Nous allons définir le nom de notre profile dans settings.py dans notre application (ici core)

AUTH_PROFILE_MODULE = 'core.CustomerProfile'

Puis le modèle de ce profile dans models/customerprofile.py

from django import forms
from django.db import models
from django.contrib.auth.models import User
class CustomerProfile(models.Model):
    id_customerprofile = models.AutoField(primary_key = True)
    user = models.ForeignKey(User, unique=True)
    surname = models.CharField(max_length=50)
    firstname = models.CharField(max_length=50)
    email = models.EmailField()
    password = forms.CharField(max_length=15, widget=forms.PasswordInput)
    id_version = models.IntegerField(default=1)

    class Meta:
        app_label='core'


On remarque que ce profile possède un lien vers une clé étrangère qui pointe sur la table auth_user

Il faut penser à ajouter le lien dans __init__.py dans votre model

from customerprofile import *

Je personnalise le formulaire car je ne veux pas afficher le champ de la Foreing Key. Je veux que l'utilisateur remplisse uniquement son nom, prénom, email et mot de passe.
{% extends "base.html" %}
{% block content %}
<form action="#" method="post" class="form-analyzer center">
{% csrf_token %}
<div class="fieldWrapper">
{{ formcustomer.surname.errors }} Nom: {{ formcustomer.surname }}</div>
<div class="fieldWrapper"><span class="Apple-tab-span" style="white-space:pre"> 
{{ formcustomer.firstname.errors }} Prénom: {{ formcustomer.firstname }}</div>
<div class="fieldWrapper">
{{ formcustomer.email.errors }} Email: {{ formcustomer.email }}</div>
<div class="fieldWrapper"><span class="Apple-tab-span" style="white-space:pre"> 
{{ formcustomer.password.errors }} Mot de passe: {{ formcustomer.password }}</div>
 <input type="submit" value="Submit" />
</form>

{% endblock %}


Et le fonctionnement dans la view.py
class CustomerProfileForm(forms.ModelForm):
    id_customerprofile = models.AutoField(primary_key = True)
    user = models.ForeignKey(User, unique=True)
    surname = forms.CharField(max_length=50)
    firstname = forms.CharField(max_length=50)
    email = forms.EmailField()
    password = forms.CharField(max_length=15, widget=forms.PasswordInput)
    id_version = models.IntegerField(default=1) # Champ forcé à 1

    class Meta:
        model = CustomerProfile
        app_label = 'core'

def join(request):
    if request.method == 'POST':
        # Création du user de base
        userDjango = User.objects.create(username=request.POST['surname'], last_name=request.POST['surname'], first_name=request.POST['firstname'], email=request.POST['email'])

        userDjango.set_password(request.POST['password'])
        userDjango.save()
        # Ajpout d'information dans le profile, on aurait pu aussi simplement ajouter l'id_version
        form = CustomerProfile()
        form.surname=request.POST['surname']
        form.firstname=request.POST['firstname']
        form.email=request.POST['email']
        form.user=userDjango
        form.save()
    else:
        form = CustomerProfileForm()
    return render_to_response('registration/createcustomer.html', {'formcustomer' : form}, context_instance=RequestContext(request))
blog comments powered by Disqus