Modèle et admin de Django

Reprenons une nouvelle app ToDo dont le modèle est ci-dessous, pour pouvoir la gérer dans l’admin.

Modèle ToDo

#models.py
class ToDo(models.Model):
    name = models.CharField(max_length=250)
    begin_date = models.DateField(auto_now_add=True)
    end_date = models.DateField()
    done = models.BooleanField(default=False)

    def __str__(self):
        return self.name

Migrations

Pour que Django prenne en compte les modifications de structure de la BD

./manage.py makemigrations
./manage.py sqlmigrate planning 0001
./manage.py migrate
  • la commande makemigrations prépare les migrations

  • la commande sqlmigrate décrit en sql la migration qui va se faire en base de données

  • La commande migrate l’effectue

Et pour voir le nouveau modèle dans l’admin de Django

Complétons à présent le fichier admin.py

# admin.py
from django.contrib import admin
from planning.models import ToDo


class ToDoAdmin(admin.ModelAdmin):
    list_display=(
    'name', 'begin_date', 'end_date','done',
)

admin.site.register(ToDo,ToDoAdmin)

Créons un superuser dans Django pour accéder à l’admin

./manage.py createsuperuser

Puis visitez l’admin: Localhost:8000/admin/ ous cette identité. Crééz quelques ToDo.

Améliorons un peu le rendu de l’admin des ToDo

@admin.register(ToDo)
class ToDoAdmin(admin.ModelAdmin):
        fieldsets = [
                ('ToDo Details', {'fields': ['name', 'done']}),
                ('ToDo Dates', {'fields': ['begin_date', 'end_date']}),
        ]

        readonly_fields = ('begin_date',)

        list_display = ('name', 'begin_date', 'end_date','done',)
        list_editable = ('done',)
        list_display_links = ('name', 'date_reviewed',)
        list_filter = ('done',)
        search_fields = ['name',]

Testez. Remarquez le décorateur qui sert à enregistrer directement le modèle ToDo dans l’admin et aussi les améliorations dans l’affichage des ToDo dans l’admin. Commitez.

Enrichissement du Modèle ToDo

Ajoutons par exemple le fait de mettre automatiquement end_date du Todo à now dès que le booléen done passe à True. Il faut pour cela surcharger la méthode save() de Model (avec ses args et kwargs, pourquoi à votre avis ?) et aussi ne pas oublier de faire appel à la méthode save() de la superclasse …

#models.py
from django.db import models
from django.utils.timezone import now

class ToDo(models.Model):
    name = models.CharField(max_length=250)
    begin_date = models.DateField(auto_now_add=True)
    end_date = models.DateField()
    done = models.BooleanField(default=False)

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if (self.done and self.end_date is None):
                self.end_date = now()

        super(ToDo, self).save(*args, **kwargs)

Réalisons les migrations.

./manage.py makemigrations
./manage.py migrate

Testez dans l’admin. Commitez.