Ce document détaille l’API des objets Model. Il augmente les contenus présentés dans les guides des modèles et des requêtes de base de données, il est donc conseillé de lire et de comprendre ces derniers avant de lire celui-ci.
Tout au long de cette référence, nous utiliserons les modèles d’exemple Weblog présentés dans le guide des requêtes de base de données.
Pour créer une nouvelle instance d’un modèle, il suffit de l’instancier comme n’importe quelle autre classe Python :
Les paramètres nommés sont simplement les noms des champs définis dans le modèle. Notez que l’instanciation d’un modèle ne touche pas à la base de données ; pour cela, il faut enregistrer avec save().
Note
Vous pourriez être tenté de personnaliser le modèle en surchargeant sa méthode __init__. Cependant, si vous faites cela, prenez soin de ne pas modifier la signature de la méthode car tout changement pourrait bloquer l’enregistrement de l’instance de modèle. Plutôt que de surcharger __init__, essayer d’utiliser l’une de ces approches :
Ajouter une méthode classmethod sur la classe du modèle :
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
@classmethod
def create(cls, title):
book = cls(title=title)
# do something with the book
return book
book = Book.create("Pride and Prejudice")
Ajouter une méthode dans un gestionnaire personnalisé (souvent plus judicieux) :
class BookManager(models.Manager):
def create_book(self, title):
book = self.create(title=title)
# do something with the book
return book
class Book(models.Model):
title = models.CharField(max_length=100)
objects = BookManager()
book = Book.objects.create_book("Pride and Prejudice")
La validation d’un modèle se déroule en trois étapes :
Validation des champs de modèle - Model.clean_fields()
Validation du modèle en entier - Model.clean()
Validation de l’unicité des champs - Model.validate_unique()
Les trois étapes sont effectuées lorsque la méthode full_clean() d’un modèle est appelée.
Lors de l’utilisation d’un formulaire ModelForm, l’appel à is_valid() effectue ces étapes de validation pour tous les champs inclus dans le formulaire. Consultez la documentation de ModelForm pour plus d’informations. L’appel à la méthode full_clean() d’un modèle ne devrait être nécessaire que lorsque l’on souhaite s’occuper soi-même des erreurs de validation ou si des champs ont été exclu du ModelForm et qu’ils nécessitent une validation.
Le paramètre validate_unique a été ajouté pour permettre de sauter Model.validate_unique(). Précédemment, Model.validate_unique() était toujours appelé par full_clean.
Cette méthode appelle Model.clean_fields(), Model.clean() et Model.validate_unique() (si validate_unique vaut True), dans cet ordre et peut générer une exception ValidationError avec un attribut message_dict contenant les erreurs produites par les trois méthodes.
Le paramètre facultatif exclude peut être utilisé pour fournir une liste de noms de champs qui peuvent être exclus de la validation et du nettoyage. ModelForm utilise ce paramètre pour exclure de la validation les champs qui sont absents du formulaire, car d’éventuelles erreurs ne pourraient pas être corrigées par l’utilisateur.
Notez que full_clean() ne sera pas appelée automatiquement lorsque vous appelez la méthode save() d’un modèle. Il faut l’appeler manuellement au moment où vous souhaitez effectuer la validation de modèle pour vos propres modèles. Par exemple :
from django.core.exceptions import ValidationError
try:
article.full_clean()
except ValidationError as e:
# Do something based on the errors contained in e.message_dict.
# Display them to a user, or handle them programatically.
pass
La première chose que fait full_clean() est de procéder au nettoyage de chaque champ individuellement.
Cette méthode valide tous les champs du modèle. Le paramètre facultatif exclude peut être utilisé pour fournir une liste de noms de champs à exclure de la validation. Une exception ValidationError est générée pour chaque champ dont la validation échoue.
La deuxième chose que fait full_clean() est d’appeler Model.clean(). Cette méthode peut être surchargée pour effectuer une validation personnalisée du modèle.
C’est cette méthode qui devrait être utilisée pour fournir une validation de modèle personnalisée et pour modifier des attributs du modèle, le cas échéant. Par exemple, on pourrait profiter de cette méthode pour attribuer une valeur automatique à un champ ou pour procéder à une validation qui nécessite de pouvoir accéder à d’autres champs du modèle :
import datetime
from django.core.exceptions import ValidationError
from django.db import models
class Article(models.Model):
...
def clean(self):
# Don't allow draft entries to have a pub_date.
if self.status == 'draft' and self.pub_date is not None:
raise ValidationError('Draft entries may not have a publication date.')
# Set the pub_date for published items if it hasn't been set already.
if self.status == 'published' and self.pub_date is None:
self.pub_date = datetime.date.today()
Notez cependant que comme pour Model.full_clean(), la méthode clean() d’un modèle n’est pas invoquée lors d’un appel à la méthode save() du modèle.
Toute exception ValidationError générée par Model.clean() est stockée dans une clé particulière d’un dictionnaire d’erreurs, NON_FIELD_ERRORS, qui est réservée aux erreurs liées au modèle dans son entier plutôt qu’à un champ spécifique :
from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
try:
article.full_clean()
except ValidationError as e:
non_field_errors = e.message_dict[NON_FIELD_ERRORS]
Finalement, full_clean() vérifie les contraintes d’unicité éventuelles du modèle.
Cette méthode est semblable à clean_fields(), mais elle valide toutes les contraintes d’unicité du modèle au lieu des valeurs de champs individuelles. Le paramètre facultatif exclude peut être utilisé pour fournir une liste de noms de champs à exclure de la validation. Une exception ValidationError est générée pour chaque champ dont la validation échoue.
Notez que si vous renseignez le paramètre exclude de validate_unique(), les contraintes unique_together impliquant l’un des champs de la liste ne seront pas contrôlées.
Pour enregistrer un objet dans la base de données, appelez save():
Si vous souhaitez personnaliser le comportement d’enregistrement, vous pouvez surcharger cette méthode save(). Voir Surcharge des méthodes de modèles prédéfinies pour plus de détails.
Le processus d’enregistrement des modèles comporte également certaines subtilités ; voir les sections ci-dessous.
Si un modèle contient un champ AutoField – une clé primaire avec incrémentation automatique – la valeur incrémentée automatiquement sera calculée et enregistrée comme attribut de l’objet lors de son premier enregistrement avec save():
>>> b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.')
>>> b2.id # Returns None, because b doesn't have an ID yet.
>>> b2.save()
>>> b2.id # Returns the ID of your new object.
Il n’est pas possible de connaître la valeur future de l’identifiant avant d’appeler save(), car cette valeur est calculée par la base de données, et non par Django.
Par commodité, chaque modèle possède par défaut un champ AutoField nommé id, sauf dans le cas où vous ajoutez explicitement le paramètre primary_key=True à l’un des champs du modèle. Consultez la documentation de AutoField pour plus de détails.
Que vous définissiez vous-même un champ de clé primaire ou que vous laissiez Django s’en charger, chaque modèle possède une propriété nommée pk. Elle se comporte comme un attribut normal du modèle, mais représente en réalité un alias vers l’attribut du modèle qui a la fonction de clé primaire. Vous pouvez lire et définir cette valeur, comme vous le feriez pour tout autre attribut, et l’action s’applique au bon champ du modèle, c’est-à-dire à la clé primaire.
Si un modèle contient un champ AutoField mais que vous souhaiteriez définir explicitement l’identifiant d’un nouvel objet lors de son enregistrement, il suffit de le faire juste avant de l’enregistrer, plutôt que de compter sur l’attribution automatique de l’identifiant :
>>> b3 = Blog(id=3, name='Cheddar Talk', tagline='Thoughts on cheese.')
>>> b3.id # Returns 3.
>>> b3.save()
>>> b3.id # Returns 3.
Si vous attribuez manuellement des valeurs de clé primaire habituellement automatiques, prenez garde de ne pas utiliser des valeurs déjà existantes ! Si vous créez un nouvel objet avec une valeur de clé primaire explicite qui existe déjà dans la base de données, Django pense que vous modifiez un objet existant, et non que vous en créez un nouveau.
En reprenant l’exemple du blog 'Cheddar Talk' ci-dessus, cet exemple écraserait l’objet existant dans la base de données :
b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.')
b4.save() # Overrides the previous blog with ID=3!
Lisez Comment Django distingue UPDATE de INSERT ci-dessous, pour comprendre pourquoi cela se passe ainsi.
La définition explicite de valeurs de clés primaires est essentiellement utile lors de l’enregistrement d’objets en vrac, lorsque l’on est à peu près certain qu’il n’y aura pas de collision de clés primaires.
Lorsque vous enregistrez un objet, Django effectue les étapes suivantes :
Émission d’un signal ``pre-save``. Le signal django.db.models.signals.pre_save est envoyé, permettant à toute fonction à l’écoute de ce signal d’entreprendre une action personnalisée.
Pré-traitement des données. Chaque champ de l’objet doit effectuer d’éventuelles transformations automatiques de données qui lui sont nécessaires.
La plupart des champs n’effectuent pas de pré-traitement, les données du champ sont laissées telles quelles. Le pré-traitement est surtout utile aux champs qui ont un comportement particulier. Par exemple, si un modèle possède un champ DateField avec auto_now=True, la phase pré-enregistrement modifie les données de l’objet pour garantir que le champ date contient la date actuelle (la documentation ne contient pas encore de liste de tous les champs présentant un comportement particulier).
Préparation des données pour la base de données. Chaque champ doit fournir sa valeur actuelle dans un type de données qui peut être écrit dans la base de données.
La plupart des champs ne nécessitent aucune préparation de données. Les types de données simples, comme les entiers ou les chaînes de caractères, sont « prêtes à l’écriture » en tant qu’objet Python. Cependant, les types de données plus complexes ont souvent besoin de certaines modifications.
Par exemple, les champs DateField utilisent un objet Python datetime pour stocker leurs données. Les bases de données ne peuvent pas stocker d’objet datetime, il faut donc que la valeur du champ soit convertie dans une chaîne date au format ISO pour être insérée dans la base de données.
Insertion des données dans la base de données. Les données pré-traitées et préparées sont ensuite converties en instruction SQL en vue de leur insertion dans la base de données.
Émission d’un signal ``post-save``. Le signal django.db.models.signals.post_save est envoyé, permettant à toute fonction à l’écoute de ce signal d’entreprendre une action personnalisée.
Vous avez peut-être remarqué que les objets de base de données de Django utilisent la même méthode save() pour créer ou modifier des objets. La couche d’abstraction de Django évite de devoir différencier les instructions SQL INSERT ou UPDATE. Plus concrètement, lors de l’appel à save(), Django suit l’algorithme suivant :
Si l’attribut de clé primaire de l’objet est défini à une valeur équivalent à True (c’est-à-dire une valeur autre que None ou que la chaîne vide), Django effectue une instruction UPDATE (mise à jour).
Si l’attribut de clé primaire de l’objet n’est pas défini où si l’instruction UPDATE n’a rien mis à jour, Django exécute une requête INSERT.
Le point délicat ici est de faire attention à ne pas indiquer explicitement de valeur de clé primaire lors de l’enregistrement de nouveaux objets, si vous ne pouvez garantir que cette clé primaire est libre. Pour plus de détails sur cette nuance, consultez Définition explicite des valeurs de clés primaires ci-dessus et Contrainte d’insertion ou de mise à jour ci-dessous.
Précédemment, Django faisait un SELECT lorsque l’attribut de clé primaire était défini. Si le SELECT trouvait un objet, Django effectuait ensuite un UPDATE, sinon il procédait à un INSERT. Cet ancien algorithme produisait une requête supplémentaire dans le cas UPDATE. Il peut arriver dans certains cas que la base de données ne signale pas qu’une ligne a été mise à jour même quand il existe une ligne de base de données correspondant à la clé primaire de l’objet. Un exemple est le déclencheur ON UPDATE de PostgreSQL qui renvoie NULL. Dans de tels cas, il est possible de revenir à l’algorithme précédent en définissant l’option select_on_save à True.
Dans de rares circonstances, il est nécessaire de pouvoir forcer la méthode save() à recourir à une instruction SQL INSERT au lieu d’une instruction UPDATE. Ou l’inverse : mettre à jour si possible, mais ne pas insérer un nouvel enregistrement. Dans ces situations, il est possible de fournir les paramètres force_insert=True ou force_update=True à la méthode save(). Il est évidemment faux de fournir les deux paramètres simultanément : il est impossible d’insérer et de mettre à jour en même temps !
L’usage de ces paramètres est très rare. Django effectue presque toujours le bon choix et en surchargeant le comportement habituel, des erreurs difficiles à détecter peuvent survenir. Cette fonctionnalité est réservée aux experts.
L’utilisation de update_fields force une mise à jour de la même façon que force_update.
Il est parfois nécessaire d’effectuer une tâche arithmétique simple sur un champ, comme l’incrémentation ou la décrémentation de la valeur actuelle. La façon évidente de le faire peut ressembler à quelque chose comme :
>>> product = Product.objects.get(name='Venezuelan Beaver Cheese')
>>> product.number_sold += 1
>>> product.save()
Si la valeur number_sold existante dans la base de données est 10, c’est la valeur 11 qui sera écrite comme nouvelle valeur en base de données.
Cette séquence présente un problème de mise à jour standard parce qu’elle contient une situation de concurrence critique. Si un autre fil d’exécution a déjà enregistré une valeur mise à jour après que le fil actuel ait lu l’ancienne valeur, le fil actuel enregistrera l’ancienne valeur plus un, au lieu de la nouvelle valeur (actuelle) plus un.
Ce processus peut être solidifié et rendu légèrement plus rapide en exprimant la mise à jour relativement à la valeur existante plutôt qu’en attribuant explicitement une nouvelle valeur. Django fournit des expressions F() pour parvenir à ce genre de mise à jour relative. En employant des expressions F(), l’exemple précédent est formulé ainsi :
>>> from django.db.models import F
>>> product = Product.objects.get(name='Venezuelan Beaver Cheese')
>>> product.number_sold = F('number_sold') + 1
>>> product.save()
Cette approche n’emploie pas la valeur initiale lue dans la base de données. Elle demande plutôt à la base de données de procéder à la mise à jour en fonction de la valeur existante au moment où la méthode save() est appelée.
Après l’enregistrement de l’objet, il faut recharger celui-ci pour pouvoir accéder à la nouvelle valeur reçue par le champ mis à jour :
>>> product = Products.objects.get(pk=product.pk)
>>> print(product.number_sold)
42
Pour plus de détails, consultez la documentation sur les expressions F() et leur emploi dans les requêtes de mise à jour.
En transmettant une liste de noms de champs dans le paramètre update_fields de save(), seuls les champs figurant dans cette liste sont mis à jour. Cela peut être judicieux lorsque un petit sous-ensemble des champs d’un objet doivent être mis à jour. Un léger gain de performances peut être espéré en évitant de mettre à jour tous les champs du modèle en base de données. Par exemple :
product.name = 'Name changed again'
product.save(update_fields=['name'])
Le paramètre update_fields peut être n’importe quel objet itérable contenant des chaînes de caractères. Si ce dernier est vide, l’enregistrement n’a pas lieu. La valeur None provoque la mise à jour de tous les champs.
L’utilisation de update_fields force une mise à jour.
Lors de l’enregistrement d’un modèle obtenu par chargement différé de modèle (only() ou defer()), seuls les champs chargés à partir de la base de données sont mis à jour. Dans ce cas, l’effet est semblable à un update_fields automatique. Si vous attribuez ou que vous modifiez l’une des valeurs de champ différé, le champ est ajouté aux champs à mettre à jour.
Effectue une instruction SQL DELETE pour l’objet. Cela ne fait que supprimer l’objet dans la base de données ; l’instance Python existe toujours et ses champs contiennent encore les données.
Pour plus de détails, y compris sur la suppression d’objets en vrac, consultez Suppression d’objets.
Si vous avez besoin d’un comportement de suppression personnalisé, vous pouvez surcharger la méthode delete(). Voir Surcharge des méthodes de modèles prédéfinies pour plus de détails.
Quelques méthodes d’objet ont un rôle spécifique.
Note
Avec Python 3, comme toutes les chaînes sont nativement considérées comme Unicode, n’utilisez que la méthode __str__() (la méthode __unicode__() étant obsolète). Si vous voulez rester compatible avec Python 2, vous pouvez décorer la classe de modèle avec python_2_unicode_compatible().
La méthode __unicode__() est appelée chaque fois que unicode() est appelée sur un objet. Django utilise unicode(obj) (ou la fonction liée, str(obj)) à plusieurs occasions. Plus particulièrement, pour afficher un objet dans le site d’administration de Django et pour produire la valeur insérée dans un gabarit lors de l’affichage d’un objet. Il est donc important de toujours renvoyer une représentation utile et intelligible du modèle en réponse à la méthode __unicode__().
Par exemple :
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
Si vous définissez une méthode __unicode__() pour un modèle et pas la méthode __str__(), Django crée automatiquement une méthode __str__() qui appelle __unicode__() et qui convertit correctement le résultat en chaîne codée en UTF-8. C’est une pratique de développement recommandée : uniquement définir __unicode__() et laisser Django se charger de la conversion en objet chaîne lorsque c’est nécessaire.
La méthode __str__() est appelée chaque fois que str() est appelée sur un objet. La principale utilité de cette méthode dans Django est lorsque le résultat repr() d’un modèle est affiché quelque part (par exemple, dans du contenu de débogage). Il est donc important de renvoyer une chaîne utile et intelligible pour la méthode __str__() des objets. Il n’est pas obligatoire d’écrire partout des méthodes __str__() quand il existe des méthodes __unicode__() appropriées.
L’exemple __unicode__() précédent pourrait être écrit de manière semblable avec __str__() comme ceci :
from django.db import models
from django.utils.encoding import force_bytes
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
def __str__(self):
# Note use of django.utils.encoding.force_bytes() here because
# first_name and last_name will be unicode strings.
return force_bytes('%s %s' % (self.first_name, self.last_name))
Définissez une méthode get_absolute_url() pour indiquer à Django la façon de calculer l’URL canonique d’un objet. Pour l’appelant, cette méthode doit renvoyer une chaîne pouvant être utilisée pour se référer à un objet par HTTP.
Par exemple :
def get_absolute_url(self):
return "/people/%i/" % self.id
(Bien que ce code soit correct et simple, ce n’est peut-être pas la manière la plus portable d’écrire ce genre de méthode. La fonction reverse() est habituellement la meilleure approche.)
Par exemple :
def get_absolute_url(self):
from django.core.urlresolvers import reverse
return reverse('people.views.details', args=[str(self.id)])
Un endroit où Django utilise get_absolute_url() est l’application d’administration. Si un objet définit cette méthode, la page d’édition d’objet présentera un lien « Voir sur le site » qui vous amène directement sur la page d’affichage public de l’objet, telle qu’indiquée par get_absolute_url().
De même, certaines autres parties de Django, comme le système de flux de syndication, utilisent get_absolute_url() lorsqu’elle est définie. Si le fait de posséder une URL unique pour chaque instance de modèle fait sens, vous devriez définir get_absolute_url().
L’utilisation de get_absolute_url() dans les gabarits est reconnu comme une bonne pratique, au lieu de figer les URL des objets à des chaînes fixes. Par exemple, ce code de gabarit est mauvais :
<!-- BAD template code. Avoid! -->
<a href="/people/{{ object.id }}/">{{ object.name }}</a>
Ce code de gabarit est bien meilleur :
<a href="{{ object.get_absolute_url }}">{{ object.name }}</a>
Ici, la logique est que si vous modifiez la structure des URL de vos objets, même s’il ne s’agissait que d’une simple correction orthographique, il n’est pas acceptable de devoir rechercher tous les endroits où l’URL en question pourrait être écrite. On la définit une seule fois dans get_absolute_url() et tous les autres endroits du code peuvent alors référencer cette méthode.
Note
La chaîne renvoyée par get_absolute_url() ne doit contenir que des caractères ASCII (exigence de la spécification d’URI RFC 2396) et être codée en syntaxe URL, si nécessaire.
Le code et les gabarits faisant appel à get_absolute_url() doivent pouvoir utiliser le résultat directement sans plus de traitement. Il peut être utile d’appeler la fonction django.utils.encoding.iri_to_uri() pour contribuer à cet objectif si vous utilisez des caractères unicode en dehors de la plage ASCII.
Avertissement
Le décorateur permalink n’est plus recommandé. Vous devriez plutôt utiliser reverse() dans le corps de la méthode get_absolute_url.
Dans de précédentes versions de Django, il n’existait pas de manière simple d’utiliser les URL définies dans le fichier de configuration d’URL dans get_absolute_url(). Cela signifiait qu’il fallait définir les URL à la fois dans la configuration d’URL et dans get_absolute_url(). Le décorateur permalink a été ajouté pour répondre à cette violation du principe DRY (non répétition). Cependant, depuis l’introduction de reverse(), il n’y a plus de raison d’utiliser permalink.
Ce décorateur accepte le nom d’un motif d’URL (soit un nom de vue ou un nom de motif d’URL) et une liste de paramètres positionnels ou nommés, et il utilise les motifs de configuration d’URL pour construire l’URL correcte et complète. Il renvoie une chaîne contenant l’URL correcte, tous les paramètres étant substitués aux bonnes positions.
Le décorateur permalink est un équivalent au niveau Python de la balise de gabarit url et un adaptateur de haut niveau pour la fonction reverse().
Un exemple devrait clarifier la façon d’utiliser permalink(). Supposons que la configuration d’URL contient une ligne telle que celle-ci :
(r'^people/(\d+)/$', 'people.views.details'),
…votre modèle pourrait posséder une méthode get_absolute_url() ressemblant à ceci :
from django.db import models
@models.permalink
def get_absolute_url(self):
return ('people.views.details', [str(self.id)])
De même, si une ligne de la configuration d’URL ressemblait à ceci :
(r'/archive/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$', archive_view)
…vous pourriez la référencer avec permalink() comme suit :
@models.permalink
def get_absolute_url(self):
return ('archive_view', (), {
'year': self.created.year,
'month': self.created.strftime('%m'),
'day': self.created.strftime('%d')})
Remarquez que nous avons défini une liste vide pour le second paramètre dans ce cas, car nous ne voulions transmettre que des paramètres nommés, pas de paramètres positionnels.
De cette façon, vous associez le chemin absolu du modèle à la vue utilisée pour l’afficher, sans répéter aucunement les informations d’URL de la vue. Vous pouvez toujours utiliser la méthode get_absolute_url() dans les gabarits, comme auparavant.
Dans certains cas, comme pour l’utilisation de vues génériques ou la réutilisation de vues personnalisées pour plusieurs modèles, l’indication de la fonction de vue peut embrouiller le résolveur d’URL inverse (parce que plusieurs motifs pointent vers la même vue). Dans cette situation, Django propose les motifs d’URL nommés. En exploitant un motif d’URL nommé, il est possible de donner un nom au motif, puis de référencer ce nom plutôt que la fonction de vue. Un motif d’URL nommé est défini en remplaçant le tuple de motif par un appel à la fonction url:
from django.conf.urls import url
url(r'^people/(\d+)/$', 'blog_views.generic_detail', name='people_view'),
…puis en utilisant ce nom pour effectuer la résolution d’URL inverse au lieu du nom de la vue :
from django.db import models
@models.permalink
def get_absolute_url(self):
return ('people_view', [str(self.id)])
Plus de détails sur les motifs d’URL nommés se trouvent dans la documentation de distribution des URL.
En plus de save() et delete(), un objet de modèle peut posséder certaines des méthodes suivantes :
Pour chaque champ ayant le paramètre choices, l’objet dispose d’une méthode get_FOO_display(), où FOO est le nom du champ. Cette méthode renvoie une valeur « intelligible » pour ce champ.
Par exemple :
from django.db import models
class Person(models.Model):
SHIRT_SIZES = (
(u'S', u'Small'),
(u'M', u'Medium'),
(u'L', u'Large'),
)
name = models.CharField(max_length=60)
shirt_size = models.CharField(max_length=2, choices=SHIRT_SIZES)
>>> p = Person(name="Fred Flintstone", shirt_size="L")
>>> p.save()
>>> p.shirt_size
u'L'
>>> p.get_shirt_size_display()
u'Large'
Pour chaque champ DateField et DateTimeField ne possédant pas le paramètre null=True, l’objet disposera de méthodes get_next_by_FOO() et get_previous_by_FOO(), où FOO est le nom du champ. Celles-ci renvoient respectivement l’objet suivant et l’objet précédent en fonction du champ date, générant une exception DoesNotExist le cas échéant.
Ces deux méthodes effectuent leurs requêtes en utilisant le gestionnaire par défaut du modèle. Si vous avez besoin d’émuler le filtrage d’un gestionnaire personnalisé ou que vous vouliez effectuer un filtrage personnalisé unique, ces deux méthodes acceptent aussi des paramètres nommés facultatifs qui devraient correspondre au format décrit dans Recherches dans les champs.
Notez qu’en cas de valeurs datées identiques, ces méthodes emploient la clé primaire pour déterminer l’objet choisi. Cela permet de garantir qu’aucun objet ne sera omis ou dupliqué. Cela signifie également qu’il n’est pas possible d’utiliser ces méthodes pour des objets non enregistrés.
Jan 13, 2016