Référence des instances de modèlesLien vers cette rubrique
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 de blog présentés dans le guide des requêtes de base de données.
Création d’objetsLien vers cette rubrique
Pour créer une nouvelle instance d’un modèle, instanciez-la comme n’importe quelle autre classe Python :
- class Model(**kwargs)Lien vers cette définition
Les paramètres nommés sont 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().
Personnalisation du chargement des modèlesLien vers cette rubrique
- classmethod Model.from_db(db, field_names, values)Lien vers cette définition
La méthode from_db() peut être utilisée pour personnaliser la création des instances de modèles lors de leur chargement à partir de la base de données.
Le paramètre db contient l’alias de la base de données à partir de laquelle le modèle est chargé, field_names contient les noms de tous les champs chargés et values contient les valeurs chargées pour chaque champ de field_names. L’ordre des champs dans field_names est le même que dans values. Si tous les champs du modèle sont présents, values est toujours dans l’ordre attendu par __init__(). Cela signifie que l’instance peut être créée par cls(*values). Si certains champs sont différés, ils n’apparaissent pas dans field_names. Dans ce cas, attribuez une valeur django.db.models.DEFERRED à chacun des champs manquants.
En plus de créer le nouveau modèle, la méthode from_db() doit définir les drapeaux adding et db de l’attribut _state de la nouvelle instance.
Dans l’exemple ci-dessous, on voit comment mémoriser les valeurs des champs telles que chargées à partir de la base de données :
from django.db.models import DEFERRED
@classmethod
def from_db(cls, db, field_names, values):
# Default implementation of from_db() (subject to change and could
# be replaced with super()).
if len(values) != len(cls._meta.concrete_fields):
values = list(values)
values.reverse()
values = [
values.pop() if f.attname in field_names else DEFERRED
for f in cls._meta.concrete_fields
]
instance = cls(*values)
instance._state.adding = False
instance._state.db = db
# customization to store the original field values on the instance
instance._loaded_values = dict(
zip(field_names, (value for value in values if value is not DEFERRED))
)
return instance
def save(self, **kwargs):
# Check how the current values differ from ._loaded_values. For example,
# prevent changing the creator_id of the model. (This example doesn't
# support cases where 'creator_id' is deferred).
if not self._state.adding and (
self.creator_id != self._loaded_values["creator_id"]
):
raise ValueError("Updating the value of creator isn't allowed")
super().save(**kwargs)
L’exemple ci-dessus montre une implémentation complète de from_db() pour clarifier son fonctionnement. Dans ce cas, il aurait été possible de faire appel à super() dans la méthode from_db().
Actualisation des objets à partir de la base de donnéesLien vers cette rubrique
Si vous supprimez un champ à partir d’une instance de modèle, un nouvel accès va recharger la valeur de la base de données :
>>> obj = MyModel.objects.first()
>>> del obj.field
>>> obj.field # Loads the field from the database
- Model.refresh_from_db(using=None, fields=None, from_queryset=None)Lien vers cette définition
- Model.arefresh_from_db(using=None, fields=None, from_queryset=None)Lien vers cette définition
Version asynchrone: arefresh_from_db()
Si vous avez besoin de recharger les valeurs d’un modèle à partir de la base de données, vous pouvez utiliser la méthode refresh_from_db(). Lorsque cette méthode est appelée sans paramètre, voici ce qui se passe :
Tous les champs non différés du modèle sont mis à jour avec les valeurs actuellement présentes en base de données.
Toutes les relations en cache sont effacées de l’instance rechargée.
Seuls les champs du modèle sont rechargés à partir de la base de données. D’autres valeurs dépendantes de la base de données telles que les annotations ne sont pas rechargées. Tout attribut @cached_property n’est pas non plus réinitialisé.
Le rechargement s’opère à partir de la base de données à l’origine des valeurs existantes, ou de la base de données par défaut si l’instance n’a pas été chargée à partir de la base de données. Le paramètre using peut être utilisé pour forcer la base de données source du rechargement.
Il est possible de forcer le groupe de champs à recharger en utilisant le paramètre fields.
Par exemple, pour tester qu’un appel à update() a effectivement produit le résultat attendu, vous pourriez écrire un test semblable à celui-ci :
def test_update_result(self):
obj = MyModel.objects.create(val=1)
MyModel.objects.filter(pk=obj.pk).update(val=F("val") + 1)
# At this point obj.val is still 1, but the value in the database
# was updated to 2. The object's updated value needs to be reloaded
# from the database.
obj.refresh_from_db()
self.assertEqual(obj.val, 2)
When a deferred field is loaded on-demand for a single model instance, the loading happens through this method. Thus it is possible to customize the way this loading happens. The example below shows how one can reload all of the instance’s fields when a deferred field is loaded on-demand:
class ExampleModel(models.Model):
def refresh_from_db(self, using=None, fields=None, **kwargs):
# fields contains the name of the deferred field to be
# loaded.
if fields is not None:
fields = set(fields)
deferred_fields = self.get_deferred_fields()
# If any deferred field is going to be loaded
if fields.intersection(deferred_fields):
# then load all of them
fields = fields.union(deferred_fields)
super().refresh_from_db(using, fields, **kwargs)
L’argument from_queryset permet d’utiliser un jeu de requête différent que celui créé par _base_manager. Cela vous donne plus de contrôle sur la manière dont l’objet est rechargé. Par exemple, lorsqu’un modèle utilise la suppression douce, vous pouvez forcer refresh_from_db() à prendre cet aspect en compte :
obj.refresh_from_db(from_queryset=MyModel.active_objects.all())
Vous pouvez mettre en cache les objets liés qui auraient été sinon effacés de l’instance rechargée :
obj.refresh_from_db(from_queryset=MyModel.objects.select_related("related_field"))
Vous pouvez verrouiller la ligne jusqu’à la fin de la transaction avant de recharger les valeurs d’un modèle :
obj.refresh_from_db(from_queryset=MyModel.objects.select_for_update())
- Model.get_deferred_fields()Lien vers cette définition
Une méthode utilitaire renvoyant un ensemble contenant les noms d’attributs de tous les champs d’un modèle qui sont actuellement différés.
Validation d’objetsLien vers cette rubrique
La validation d’un modèle se déroule en quatre é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()Validation des contraintes -
Model.validate_constraints()
Les quatre é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.
- Model.full_clean(exclude=None, validate_unique=True, validate_constraints=True)Lien vers cette définition
Cette méthode appelle Model.clean_fields(), Model.clean(), Model.validate_unique() (si validate_unique vaut True) et Model.validate_constraints() (si validate_constraints vaut True), dans cet ordre et peut générer une exception ValidationError avec un attribut message_dict contenant les erreurs produites par les quatre méthodes.
Le paramètre facultatif exclude peut être utilisé pour fournir un ensemble set 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 programmatically.
pass
La première chose que fait full_clean() est de procéder au nettoyage de chaque champ individuellement.
- Model.clean_fields(exclude=None)Lien vers cette définition
Cette méthode valide tous les champs du modèle. Le paramètre facultatif exclude peut être utilisé pour fournir un ensemble set 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.
- Model.clean()Lien vers cette définition
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
from django.utils.translation import gettext_lazy as _
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.
Dans l’exemple ci-dessus, l’exception ValidationError générée par Model.clean() a été créée en lui passant une chaîne, elle sera donc stockée dans une clé particulière d’un dictionnaire d’erreurs, NON_FIELD_ERRORS. Cette clé 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 NON_FIELD_ERRORS, ValidationError
try:
article.full_clean()
except ValidationError as e:
non_field_errors = e.message_dict[NON_FIELD_ERRORS]
Pour attribuer une exception à un champ particulier, créez une instance de ValidationError avec un dictionnaire dont les clés correspondent aux noms de champs. Nous pourrions mettre à jour l’exemple précédent en attribuant l’erreur au champ pub_date:
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(
{"pub_date": _("Draft entries may not have a publication date.")}
)
...
Si vous détectez des erreurs dans plusieurs champs pendant Model.clean(), il est aussi possible de passer un dictionnaire faisant correspondre des noms de champs aux erreurs :
raise ValidationError(
{
"title": ValidationError(_("Missing title."), code="required"),
"pub_date": ValidationError(_("Invalid date."), code="invalid"),
}
)
Puis, full_clean() vérifie les contraintes d’unicité du modèle.
- Model.validate_unique(exclude=None)Lien vers cette définition
Cette méthode est semblable à clean_fields(), mais elle valide les contraintes d’unicité définies via attr:.Field.unique, Field.unique_for_date, Field.unique_for_month, Field.unique_for_year ou Meta.unique_together sur le modèle au lieu des valeurs de champs individuelles. Le paramètre facultatif exclude peut être utilisé pour fournir un ensemble set de noms de champs à exclure de la validation. Une exception ValidationError est générée pour chaque champ dont la validation échoue.
Les contraintes UniqueConstraint définies dans Meta.constraints sont validées par Model.validate_constraints().
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.
Finalement, full_clean() vérifie les autres contraintes éventuelles du modèle.
- Model.validate_constraints(exclude=None)Lien vers cette définition
Cette méthode valide toutes les contraintes définies dans Meta.constraints. Le paramètre facultatif exclude permet de fournir un ensemble set de noms de champs à exclure de la validation. Une exception ValidationError est générée pour chaque contrainte dont la validation échoue.
Enregistrement d’objetsLien vers cette rubrique
Pour enregistrer un objet dans la base de données, appelez save():
- Model.save(*, force_insert=False, force_update=False, using=DEFAULT_DB_ALIAS, update_fields=None)Lien vers cette définition
- Model.asave(*, force_insert=False, force_update=False, using=DEFAULT_DB_ALIAS, update_fields=None)Lien vers cette définition
Version asynchrone: asave()
Pour plus de détails sur les arguments force_insert et force_update, lisez Contrainte d’insertion ou de mise à jour. Vous pouvez aussi trouver des détails sur l’argument update_fields dans la section Indication des champs à enregistrer.
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.
Incrémentation automatique des clés primairesLien vers cette rubrique
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 b2 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.
La propriété pkLien vers cette rubrique
- Model.pkLien vers cette définition
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 le ou les champs composant la clé primaire du modèle. Vous pouvez lire et définir cette valeur, comme vous le feriez pour tout autre attribut, et l’action s’appliquera au(x) bon(s) champ(s) du modèle.
Définition explicite des valeurs de clés primairesLien vers cette rubrique
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, définissez-le explicitement 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.
Si vous utilisez PostgreSQL, la séquence associée à la clé primaire pourrait devoir être mise à jour ; voir Indication manuelle des valeurs de clé primaire avec autoincrémentation.
Que se passe-t-il lors de l’enregistrement ?Lien vers cette rubrique
Lorsque vous enregistrez un objet, Django effectue les étapes suivantes :
Émission d’un signal avant enregistrement. Le signal
django.db.models.signals.pre_saveest envoyé, permettant à toute fonction à l’écoute de ce signal d’accomplir une action.Préparation des données. La méthode
pre_save()de chaque champ est appelée pour effectuer toute éventuelle modification automatique de données. Par exemple, les champs date/heure surchargentpre_save()pour implémenterauto_now_addetauto_now.Préparation des données pour la base de données. La méthode
get_db_prep_save()de 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
DateFieldutilisent un objet Pythondatetimepour stocker leurs données. Les bases de données ne peuvent pas stocker d’objetdatetime, 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 converties en instruction SQL en vue de leur insertion dans la base de données.
Émission d’un signal après enregistrement. Le signal
django.db.models.signals.post_saveest envoyé, permettant à toute fonction à l’écoute de ce signal d’accomplir une action.
Comment Django distingue UPDATE de INSERTLien vers cette rubrique
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() et que l’attribut clé primaire de l’objet ne définit pas de valeur default ou db_default, Django suit l’algorithme suivant :
Si l’attribut de clé primaire de l’objet est défini à tout autre chose que
None, Django exécute une instructionUPDATE.Si l’attribut de clé primaire de l’objet n’est pas défini où si l’instruction
UPDATEn’a rien mis à jour (par ex. si la clé primaire est définie à une valeur qui n’existe pas en base de données), Django exécute une requêteINSERT.
Si l’attribut clé primaire de l’objet définit une valeur par défaut default ou db_default, Django exécute une instruction UPDATE s’il s’agit d’une instance de modèle existante et que sa clé primaire est définie à une valeur qui existe dans la base de données. Sinon, Django exécute une instruction 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.
Jusqu’à Django 1.5, 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.
Contrainte d’insertion ou de mise à jourLien vers cette rubrique
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 faux de fournir les deux paramètres simultanément : il est impossible d’insérer et de mettre à jour en même temps !
Dans les cas d’héritage multi-table, il est aussi possible de fournir un tuple de classes parentes à force_insert afin de forcer des instructions INSERT pour chaque classe de base. Par exemple :
Restaurant(pk=1, name="Bob's Cafe").save(force_insert=(Place,))
Restaurant(pk=1, name="Bob's Cafe", rating=4).save(force_insert=(Place, Rating))
Vous pouvez transmettre force_insert=(models.Model,) pour forcer une instruction INSERT pour tous les parents. Par défaut, force_insert=True ne force que l’insertion d’une nouvelle ligne pour le modèle actuel.
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.
Mise à jour d’attributs basés sur des champs existantsLien vers cette rubrique
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. Une façon de faire cela serait d’effectuer l’arithmétique en Python comme ceci :
>>> 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.
The process can be made robust, avoiding a race condition, as well as slightly faster by expressing the update relative to the original field value, rather than as an explicit assignment of a new value. Django provides Expressions F() for performing this kind of relative update. Using Expressions F(), the previous example is expressed as:
>>> from django.db.models import F
>>> product = Product.objects.get(name="Venezuelan Beaver Cheese")
>>> product.number_sold = F("number_sold") + 1
>>> product.save()
For more details, see the documentation on Expressions F() and their use in update queries.
Indication des champs à enregistrerLien vers cette rubrique
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.
Suppression d’objetsLien vers cette rubrique
- Model.delete(using=DEFAULT_DB_ALIAS, keep_parents=False)Lien vers cette définition
- Model.adelete(using=DEFAULT_DB_ALIAS, keep_parents=False)Lien vers cette définition
Version asynchrone: adelete()
Issues an SQL DELETE for the object. This only deletes the object in the
database; the Python instance will still exist and will still have data in
its fields, except for the primary key set to None. This method returns the
number of objects deleted and a dictionary with the number of deletions per
object type. The return value will count instances from related models if
Django is emulating cascade behavior via Python on_delete
variants. Otherwise, for database variants such as
DB_CASCADE, the return value will report only
instances of the QuerySet’s model.
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.
Il peut arriver parfois qu’avec l’héritage multi-table, on ne veuille supprimer que les données d’un modèle enfant. En indiquant keep_parents=True, les données du modèle parent sont conservées.
Sérialisation « pickle » d’objetsLien vers cette rubrique
Lorsqu’on utilise pickle sur un modèle, son état actuel est sérialisé. Lors de la désérialisation, il contiendra l’instance de modèle telle qu’elle était au moment de sa sérialisation, et non pas dans l’état actuel des données de la base de données.
Autres méthodes d’instance de modèleLien vers cette rubrique
Quelques méthodes d’objet ont un rôle spécifique.
__str__()Lien vers cette rubrique
- Model.__str__()Lien vers cette définition
La méthode __str__() est appelée chaque fois que str() est appelée sur un objet. Django utilise 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 __str__().
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 __str__(self):
return f"{self.first_name} {self.last_name}"
__eq__()Lien vers cette rubrique
- Model.__eq__()Lien vers cette définition
La méthode d’égalité est définie telle que des instances avec la même valeur de clé primaire et la même classe concrète sont considérées comme égales, sauf pour les instances dont la valeur de clé primaire est None qui ne sont toujours égales qu’à elles-mêmes. Pour les modèles mandataires, la classe concrète est définie comme le premier parent non mandataire du modèle ; pour tous les autres modèles, c’est simplement la classe du modèle.
Par exemple :
from django.db import models
class MyModel(models.Model):
id = models.AutoField(primary_key=True)
class MyProxyModel(MyModel):
class Meta:
proxy = True
class MultitableInherited(MyModel):
pass
# Primary keys compared
MyModel(id=1) == MyModel(id=1)
MyModel(id=1) != MyModel(id=2)
# Primary keys are None
MyModel(id=None) != MyModel(id=None)
# Same instance
instance = MyModel(id=None)
instance == instance
# Proxy model
MyModel(id=1) == MyProxyModel(id=1)
# Multi-table inheritance
MyModel(id=1) != MultitableInherited(id=1)
__hash__()Lien vers cette rubrique
- Model.__hash__()Lien vers cette définition
The __hash__() method is based on the instance’s primary key value. It
is effectively hash(obj.pk). If the instance doesn’t have a primary key
value then a TypeError will be raised (otherwise the __hash__()
method would return different values before and after the instance is
saved), but changing the __hash__() value of an instance is
forbidden in Python.
get_absolute_url()Lien vers cette rubrique
- Model.get_absolute_url()Lien vers cette définition
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
While this code is correct and simple, it may not be the most portable way
to write this kind of method. The reverse() function is
usually the best approach.
Par exemple :
def get_absolute_url(self):
from django.urls import reverse
return reverse("people-detail", kwargs={"pk": self.pk})
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 petite 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.
Méthodes d’instances supplémentairesLien vers cette rubrique
En plus de save() et delete(), un objet de modèle peut posséder certaines des méthodes suivantes :
- Model.get_FOO_display()Lien vers cette définition
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 = {
"S": "Small",
"M": "Medium",
"L": "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
'L'
>>> p.get_shirt_size_display()
'Large'
- Model.get_next_by_FOO(**kwargs)Lien vers cette définition
- Model.get_previous_by_FOO(**kwargs)Lien vers cette définition
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.
Autres attributsLien vers cette rubrique
_stateLien vers cette rubrique
- Model._stateLien vers cette définition
L’attribut
_statefait référence à un objetModelStatequi suit le cycle de vie de l’instance du modèle.The
ModelStateobject has three attributes:adding, a flag which isTrueif the model has not been saved to the database yet,db, a string referring to the database alias the instance was loaded from or saved to, andfetch_mode, the fetch mode to be used in subsequent field fetches.Newly instantiated instances have
adding=Trueanddb=None, since they are yet to be saved, andfetch_mode=models.FETCH_ONE. Instances fetched from aQuerySetwill haveadding=False,dbset to the alias of the associated database, andfetch_modecopied from the queryset’s fetch mode.
_is_pk_set()Lien vers cette rubrique
- Model._is_pk_set()Lien vers cette définition
The
_is_pk_set()method returns whether the model instance’spkis set. It abstracts the model’s primary key definition, ensuring consistent behavior regardless of the specificpkconfiguration. ADatabaseDefaulton an unsaved instance is considered unset.