Mise en route de Django

Mappeur objet / relationnel

Modèles de données peuvent être définis entièrement en Python. DJango met à disposition une API riche et dynamique de base de données-accès gratuitement, mais il est toujours possible d’écrire du SQL si nécessaire.

Indice

La documentation suivante est basée sur l’officiel documentation du projet Django.

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Band(models.Model):
    """A model of a rock band."""
    name = models.CharField(max_length=200)
    can_rock = models.BooleanField(default=True)


class Member(models.Model):
    """A model of a rock band member."""
    name = models.CharField("Member's name", max_length=200)
    instrument = models.CharField(choices=(
            ('g', "Guitar"),
            ('b', "Bass"),
            ('d', "Drums"),
        ),
        max_length=1
    )
    band = models.ForeignKey("Band")

Modèles

Un modèle est une classe de Python qui contient les domaines essentiels et les comportements des données stockées sur le DB. Généralement, les cartes de chaque modèle à une table de base de données unique.

  • Chaque modèle est une classe de Python que sous-classes django.db.models.Model.

  • Chaque attribut du modèle représente un champ de base de données.

  • Un modèle est une API de base de données-accès généré automatiquement ; Voir Faire des requêtes.

Petit exemple

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

Ce modèle de l’exemple définit une Person, qui a un prenom et last_name :

1
2
3
4
5
from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

prénom et last_name sont des champs du modèle. Chaque champ est spécifié comme un attribut de classe, et chaque attribut est mappé à une colonne de base de données.

Le modèle Person créerait une table de base de données comme ceci :

1
2
3
4
5
CREATE TABLE myapp_person (
    "id" serial NOT NULL PRIMARY KEY,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL
);

Notes techniques:

  • Le nom de la table, myapp_person, est dérivé automatiquement des métadonnées de modèle mais peut être substituée.

  • Un id champ est ajouté automatiquement, mais ce comportement peut être substitué.

  • Le CREATE TABLE SQL dans cet exemple est formaté à l’aide de la syntaxe de PostgreSQL, mais cela vaut la peine notant Django utilise SQL adapté à la base de données principale spécifiée dans le fichier de paramètres.

En utilisant des modèles

Une fois que les modèles ont été définis, Django il faut indiquer sur la façon d’utiliser ces modèles. Ceci est possible en modifiant le fichier de paramètres de DJango et en changeant le paramètre INSTALLED_APPS pour ajouter le nom du module qui contient le modèle classe.

Par exemple, si les modèles d’application est définie dans le module myapp.models, **INSTALLED_APPS ** doit se lire, en partie :

1
2
3
4
5
INSTALLED_APPS = (
    #...
    'myapp',
    #...
)

Avertissement

Lorsque vous ajoutez de nouvelles applications à INSTALLED_APPS, assurez-vous d’exécuter manage.py migrate, éventuellement faire des migrations pour eux tout d’abord avec manage.py makemigrations.

Note

GeoNode utilise la commande spécifique manage.py syncdb pour effectuer la mise à jour de modèles et de la migration.

Champs

La liste des champs DB est réfléchie (et spécifiée) par les attributs de classe modèle.

Avertissement

Veillez à ne pas choisir des noms de domaine que le conflit avec les modèles API comme propre, enregistrer ou supprimer.

Exemple:

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from django.db import models

class Musician(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    instrument = models.CharField(max_length=100)

class Album(models.Model):
    artist = models.ForeignKey(Musician)
    name = models.CharField(max_length=100)
    release_date = models.DateField()
    num_stars = models.IntegerField()

Plus: Field Types

Méthodes de modèle

Méthodes personnalisées sur un modèle peuvent servir à ajouter des fonctionnalités personnalisées « row-level » en objet. Il s’agit d’une technique précieuse pour garder la logique métier en un seul endroit.

Par exemple, le modèle suivant a quelques méthodes personnalisées :

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    birth_date = models.DateField()

    def baby_boomer_status(self):
        "Returns the person's baby-boomer status."
        import datetime
        if self.birth_date < datetime.date(1945, 8, 1):
            return "Pre-boomer"
        elif self.birth_date < datetime.date(1965, 1, 1):
            return "Baby boomer"
        else:
            return "Post-boomer"

    def _get_full_name(self):
        "Returns the person's full name."
        return '%s %s' % (self.first_name, self.last_name)
    full_name = property(_get_full_name)

La dernière méthode dans cet exemple est une propriété.

Le modèle de référence d’instance a une liste complète des méthodes automatiquement données à chaque modèle. Il est possible de substituer la plupart d’entre eux ; Voir substituant prédéfinis méthodes modèle

Plus: Models Methods

Faire des requêtes

Django donne automatiquement une API d’abstraction de base de données qui permet de créer, récupérer, mettre à jour et supprimer des objets.

Par exemple:

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

 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
from django.db import models

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Author(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Entry(models.Model):
    blog = models.ForeignKey(Blog)
    headline = models.CharField(max_length=255)
    body_text = models.TextField()
    pub_date = models.DateField()
    mod_date = models.DateField()
    authors = models.ManyToManyField(Author)
    n_comments = models.IntegerField()
    n_pingbacks = models.IntegerField()
    rating = models.IntegerField()

    def __str__(self):              # __unicode__ on Python 2
        return self.headline

Création d’objets

Comme déjà dit précédemment, une classe de modèle représente une table de base de données, et une instance de cette classe représente un enregistrement dans la table de base de données.

Pour créer un objet, instancier à l’aide des arguments de mot-clé à la classe de modèle, puis appelez save() pour l’enregistrer dans la base de données.

En supposant que les modèles en direct dans un fichier mysite/blog/models.py, voici un exemple :

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

1
2
3
>>> from blog.models import Blog
>>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
>>> b.save()

Il effectue un instruction INSERT SQL dans les coulisses. Django ne touche pas la base de données jusqu’à ce que vous appeliez explicitement save(). Le méthode save() n’a aucune valeur de retour.

1
2
>>> b5.name = 'New name'
>>> b5.save()

Il effectue un mise à jour UPDATE SQL déclaration dans les coulisses. Django ne touche pas la base de données jusqu’à ce que vous appeliez explicitement save().

Récupération des objets

Récupérer des objets de la base de données peut se faire en construisant une QuerySet via un Manager sur la classe de modèle.

A QuerySet représente une collection d’objets de la base de données. Il peut avoir zéro, un ou plusieurs filtres. Filtres à affiner les résultats de la requête fondées sur les paramètres donnés. En termes SQL, un QuerySet équivaut à un ** instruction SELECT et un filtre est une clause limitante comme WHERE ou LIMIT.

Chaque modèle possède au moins un Manager et qu’il est appelé objects par défaut.

Il est accessible directement via la classe de modèle, comme suit :

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

1
2
3
4
5
6
7
8
>>> Blog.objects
<django.db.models.manager.Manager object at ...>
>>> b = Blog(name='Foo', tagline='Bar')
>>> b.objects
Traceback:
    ...
AttributeError: "Manager isn't accessible via Blog instances."
Note

Cadres sont accessibles uniquement via les classes du modèle, plutôt que les instances de modèle, à * appliquer une séparation * entre les opérations de “niveau de la table” et “au niveau des enregistrements”. Le ** gestionnaire ** est la principale source de ** QuerySets ** pour un modèle. Par exemple, ‘’ Blog.objects.all()’’ retourne un ** QuerySet ** qui contient tous les objets de Blog dans la base de données.

La façon la plus simple pour récupérer des objets d’une table est d’obtenir l’ensemble d’entre eux. Pour ce faire, utilisez le all() méthode sur un Manager:

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

1
>>> all_entries = Entry.objects.all()

Le all() méthode retourne un QuerySet de tous les objets dans la base de données. Le QuerySet retourné par all() décrit tous les objets de la table de base de données. Pour sélectionner uniquement un sous-ensemble d’un ensemble complet d’objets, il doit être amélioré par l’ajout de conditions de filtre.

Les deux façons principales d’affiner un QuerySet sont :

filter(**kwargs)

Retourne un nouveau QuerySet contenant des objets qui correspondent aux paramètres de recherche donnée.

exclude(**kwargs)

Retourne un nouveau QuerySet contenant des objets qui ne correspondent pas les paramètres de recherche donnée. Les paramètres de recherche (**kwargs dans les définitions de fonction ci-dessus) doit être au format décrit dans Field recherches ci-dessous.

Par exemple, pour obtenir un QuerySet des entrées de blog par rapport à l’année 2006, utiliser filter() comme suit :

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

1
Entry.objects.filter(pub_date__year=2006)

Avec la classe de gestionnaire par défaut, c’est le même que :

1
Entry.objects.all().filter(pub_date__year=2006)

Le résultat de raffinage un QuerySet est en soi un QuerySet, il est donc possible de raffinements chaîne ensemble.

Par exemple:

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

1
2
3
4
5
6
7
>>> Entry.objects.filter(
...     headline__startswith='What'
... ).exclude(
...     pub_date__gte=datetime.date.today()
... ).filter(
...     pub_date__gte=datetime(2005, 1, 30)
... )

Cela prend l’initiale QuerySet de toutes les entrées de la base de données, ajoute un filtre, puis une exclusion, puis un autre filtre. Le résultat final est un QuerySet contenant toutes les entrées avec un titre qui commence par « Quoi », qui ont été publiés entre le 30 janvier 2005 et la date du jour.

Plus: Faire des requêtes

URL et vues

Un schéma d’URL propre élégant est un détail important dans une application Web de haute qualité. Django encourage la belle conception de l’URL et ne met pas indésirable dans les URL, comme .php ou .asp.

Dans DJango, un module Python appelé URLconf est comme une table des matières d’application. Il contient un simple mappage entre modèles d’URL et le vues.

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

1
2
3
4
5
6
7
8
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^bands/$', views.band_listing, name='band-list'),
    url(r'^bands/(\d+)/$', views.band_detail, name='band-detail'),
    url(r'^bands/search/$', views.band_search, name='band-search'),
]
1
2
3
4
5
6
from django.shortcuts import render

def band_listing(request):
    """A view of all bands."""
    bands = models.Band.objects.all()
    return render(request, 'bands/band_listing.html', {'bands': bands})

Plus: URL dispatcher

Mises à jour

Langage de template de Django permet aux développeurs de mettre la logique dans le code HTML :

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<html>
  <head>
    <title>Band Listing</title>
  </head>
  <body>
    <h1>All Bands</h1>
    <ul>
    {% for band in bands %}
      <li>
        <h2><a href="{{ band.get_absolute_url }}">{{ band.name }}</a></h2>
        {% if band.can_rock %}<p>This band can rock!</p>{% endif %}
      </li>
    {% endfor %}
    </ul>
  </body>
</html>

Plus: Templates

Formulaires

Django fournit une bibliothèque qui gère le rendu des formulaires HTML, validation des données fournies par les utilisateurs et en convertissant les données pour les types natifs de Python. Django fournit également un moyen de générer des formes de vos modèles existants et d’utiliser ces formes pour créer et mettre à jour les données.

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

1
2
3
4
5
6
7
from django import forms

class BandContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField()
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)

GET et POST

GET et POST sont les seules méthodes HTTP à utiliser lorsqu’il s’agit de formes.

Formulaire de connexion de Django est retourné à l’aide de la POST méthode, dans laquelle les faisceaux de navigateur, les données de formulaire, il code pour la transmission, il envoie au serveur et puis reçoit sa réponse.

GET, en revanche, regroupe les données soumises dans une chaîne et l’utilise pour composer une URL. L’URL contient l’adresse où doivent être envoyées les données, ainsi que les données clés et les valeurs. Vous pouvez voir cela en action si vous effectuez une recherche dans la documentation de Django, qui produira une URL de la forme https://docs.djangoproject.com/search/?q=forms&release=1.

GET et POST sont généralement utilisés à des fins différentes.

Toute demande qui pourrait être utilisé pour modifier l’état du système - par exemple, une demande qui apporte des modifications dans la base de données - doit utiliser POST. GET doit être utilisé uniquement pour les demandes qui n’affectent pas l’état du système.

GET serait également impropre à une forme de mot de passe, parce que le mot de passe apparaît dans l’URL, et donc, aussi dans l’histoire de navigateur et le serveur, tous les journaux en texte brut. Il ne serait pas approprié pour de grandes quantités de données, ou pour des données binaires, comme une image. Une application Web qui utilise GET demandes pour des formes d’administration est un risque de sécurité: il peut être facile pour un attaquant pour imiter la demande d’un formulaire pour accéder à des parties sensibles du système. POST, couplé avec d’autres protections comme la protection CSRF de Django offre plus de contrôle sur l’accès.

En revanche, GET convient pour des choses comme la recherche d’un web form, car les URL qui représentent un demande GET facilement peut être mis en signet, partagé ou soumis de nouveau.

Plus: Working With Forms

Authentification

Django utilise un système d’authentification complet et sûr. Il gère les comptes d’utilisateurs, les groupes, les autorisations et les sessions utilisateur basée sur les cookies.

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

1
2
3
4
5
6
7
from django.contrib.auth.decorators import login_required
from django.shortcuts import render

@login_required
def my_protected_view(request):
    """A view that can only be accessed by logged-in users"""
    return render(request, 'protected.html', {'current_user': request.user})

Plus: User authentication in Django

Administrateur

Une des parties plus puissants de Django est son interface d’administration automatique. Il lit les métadonnées des modèles afin de fournir une interface utilisateur graphique puissante et prêt à l’emploi pour opérations CRUD selon le modèle.

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from django.contrib import admin
from bands.models import Band, Member

class MemberAdmin(admin.ModelAdmin):
    """Customize the look of the auto-generated admin for the Member model"""
    list_display = ('name', 'instrument')
    list_filter = ('band',)

admin.site.register(Band)  # Use the default options
admin.site.register(Member, MemberAdmin)  # Use the customized options

Note

L’atelier avancé pour les développeurs fournira plus de détails sur GeoNode des modèles spécifiques et interface d’administration

Plus: The Django admin site

Internationalisation

Django offre un support complet pour la traduction du texte dans des langues différentes, plus spécifiques aux paramètres régionaux de mise en forme des dates, des heures, des nombres et des fuseaux horaires. Il permet aux développeurs et créateurs de modèles spécifient quelles sont les parties de leurs applications doivent être traduits ou formatés pour les cultures et les langues locales, et il utilise ces crochets pour localiser des applications Web pour des utilisateurs particuliers selon leurs préférences.

Note

Les exemples suivants proviennent de la documentation officielle de Django dans le seul but d’introduire les concepts généraux.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from django.shortcuts import render
from django.utils.translation import ugettext

def homepage(request):
    """
    Shows the homepage with a welcome message that is translated in the
    user's language.
    """
    message = ugettext('Welcome to our site!')
    return render(request, 'homepage.html', {'message': message})
 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
{% load i18n %}
<html>
  <head>
    <title>{% trans 'Homepage - Hall of Fame' %}</title>
  </head>
  <body>
    {# Translated in the view: #}
    <h1>{{ message }}</h1>
    <p>
      {% blocktrans count member_count=bands.count %}
      Here is the only band in the hall of fame:
      {% plural %}
      Here are all the {{ member_count }} bands in the hall of fame:
      {% endblocktrans %}
    </p>
    <ul>
    {% for band in bands %}
      <li>
        <h2><a href="{{ band.get_absolute_url }}">{{ band.name }}</a></h2>
        {% if band.can_rock %}<p>{% trans 'This band can rock!' %}</p>{% endif %}
      </li>
    {% endfor %}
    </ul>
  </body>
</html>

Note

L’atelier avancé pour les développeurs fournira plus de détails sur la façon de créer des langues et traductions sur l’utilisation de GeoNode Transifex

Plus: Internationalization and localization

Sécurité

Django dispose de multiples protections contre :

  • Détournement de clic

    Clickjacking est un type d’attaque où un site malveillant encapsule un autre site dans un cadre. Cette attaque peut entraîner par un utilisateur non averti dupé en effectuant des actions inattendues sur le site cible.

    Le X-Frame-Options middleware contenu dans un formulaire permettent un prise en charge navigateur empêcher un site d’être restitués à l’intérieur d’un cadre

  • Cross site scripting (XSS)

    Les attaques XSS permettent à un utilisateur d’injecter des scripts côté client dans les navigateurs des autres utilisateurs. Ceci est habituellement réalisé en stockant les scripts malveillants dans la base de données où il sera récupéré et affiché aux autres utilisateurs, ou en obtenant les utilisateurs à cliquer sur un lien qui va provoquer JavaScript de l’attaquant à être exécuté par le navigateur de l’utilisateur. Cependant, les attaques XSS peuvent provenir de toute source non fiable des données, telles que les cookies ou les services Web, chaque fois que les données ne sont pas suffisamment filtrées avant d’y compris dans une page.

  • Cross-Site Request Forgery (CSRF)

    Les attaques CSRF permettent à un utilisateur malveillant d’exécuter des actions en utilisant les informations d’identification d’un autre utilisateur sans la connaissance ou le consentement de l’utilisateur.

    CSRF protection fonctionne en recherchant un nonce dans chaque requête POST. Cela fait en sorte qu’un utilisateur malveillant ne peut pas simplement « rejouer » un POST de formulaire à votre site Web et avoir un autre utilisateur connecté sans le vouloir soumettre ce formulaire. L’utilisateur malveillant devra connaître le nonce, qui est l’utilisateur spécifique (à l’aide d’un cookie).

  • Injection SQL

    Injection SQL est un type d’attaque où un utilisateur malveillant est capable d’exécuter du code arbitraire SQL sur une base de données. Cela peut entraîner dans les dossiers en cours de suppression ou de fuites de données.

  • Validation d’en-tête hôte

    Django utilise le Accueil en-tête fournie par le client pour construire des URL dans certains cas. Bien que ces valeurs sont désinfectées pour prévenir des attaques Cross Site Scripting, un faux Accueil valeur peut être utilisée pour Cross-Site Request Forgery, cache attaques d’empoisonnement et l’empoisonnement des liens dans les e-mails.

    Parce que les configurations de serveur web sécurisé même apparemment sont susceptibles d’être faux Accueil en-têtes, Django valide hôte en-têtes contre le ALLOWED_HOSTS paramètre dans la méthode de``django.http.HttpRequest.get_host()``.

    Cette validation s’applique uniquement get_host(); Si votre code accède directement à partir de l’en-tête d’hôte request.META vous êtes contourner cette protection de sécurité.

  • SSL/HTTPS

    Il est toujours préférable pour la sécurité, mais pas toujours pratique dans tous les cas, pour déployer votre site derrière HTTPS. Sans cela, il est possible pour les utilisateurs de réseau malveillant de renifler les informations d’authentification ou d’autres informations transférées entre le client et le serveur et dans certains cas – les attaquants réseau actif – de modifier les données qui sont envoyées dans les deux sens.

    Django fournit certains paramètres pour sécuriser votre site unser SSL/HTTPS.

Avertissement

Alors que Django offre une bonne sécurité protection out of the box, il est toujours important déployer votre application correctement et de tirer parti de la protection de la sécurité du serveur Web, système d’exploitation et d’autres composants.

  • Assurez-vous que votre code Python est à l’extérieur de la racine du serveur Web. Cela fera en sorte que votre Python code n’est pas accidentellement servi sous forme de texte brut (ou accidentellement exécuté).

  • Faites attention avec tous les fichiers utilisateur téléchargée.

  • Django ne pas throttle demandes pour authentifier les utilisateurs. Pour se protéger contre les attaques en force contre le système d’authentification, vous pouvez envisager de déployer un plugin de Django ou le module de serveur Web d’étrangler ces demandes.

  • Gardez votre SECRET_KEY un secret.

  • C’est une bonne idée pour limiter l’accessibilité de votre cache système et base de données à l’aide d’un pare-feu.

Plus: Security in Django