django modèles abstraits rapport régulier de l'héritage
En plus de la syntaxe, quelle est la différence entre l'utilisation d'un django modèle abstrait et à l'aide de la plaine Python héritage avec django modèles? Les avantages et les inconvénients?
Mise à JOUR: je pense que ma question a été mal compris et j'ai reçu les réponses de la différence entre un modèle abstrait et une classe qui hérite de django.db.modèles.De modèle. En fait je veux savoir la différence entre un modèle de classe qui hérite de django classe abstraite (Meta: abstract = True) et une plaine Python classe qui hérite de dire, "objet" (et pas des modèles.Modèle).
Voici un exemple:
class User(object):
first_name = models.CharField(..
def get_username(self):
return self.username
class User(models.Model):
first_name = models.CharField(...
def get_username(self):
return self.username
class Meta:
abstract = True
class Employee(User):
title = models.CharField(...
- C'est un excellent aperçu des compromis entre l'utilisation des deux l'héritage des approches charlesleifer.com/blog/django-patterns-model-inheritance
Vous devez vous connecter pour publier un commentaire.
Django ne fera que générer des tables pour les sous-classes de
models.Model
, de sorte que l'ancien......va provoquer un tableau unique généré, le long des lignes de...
...alors que celui-ci...
...ne causera pas de tables à être généré.
Vous pouvez utiliser l'héritage multiple pour faire quelque chose comme ça...
...qui permettrait de créer un tableau, mais il ignore les champs définis dans la
User
classe, de sorte que vous finirez avec un tableau comme celui-ci...models.Model
, de sorte que les champs définis dans la super-classe ne sera pas ramassé (sauf s'ils sont également des sous-classes demodels.Model
).Un modèle abstrait crée un tableau avec l'ensemble des colonnes pour chaque subchild, tandis que l'utilisation de "plaine" Python héritage crée un ensemble de tables liées (aka "multi-héritage de table"). Considérons le cas où vous avez deux modèles:
Si
Vehicle
est un modèle abstrait, vous aurez un seul tableau:Toutefois, si vous utilisez de la plaine Python héritage, vous aurez deux tables:
Où
vehicle_id
est un lien vers une ligne dansapp_vehicle
aussi le nombre de roues de la voiture.Maintenant, Django va mettre cela ensemble joliment en forme d'objet, de sorte que vous pouvez accéder à
num_wheels
comme un attribut surCar
, mais la représentation sous-jacente dans la base de données sera différent.Mise à jour
À l'adresse de mise à jour de votre question, la différence entre l'héritage de Django classe abstraite et héritant de Python
object
est que le premier est considéré comme un objet de base de données (tables sont synchronisés avec la base de données) et il a le comportement d'unModel
. Héritage d'une plaine Pythonobject
donne de la classe et de ses sous-classes) aucune de ces qualités.models.OneToOneField(Vehicle)
revient à hériter d'une classe de modèle, non? Et qui aurait pour résultat de deux tableaux distincts, n'est-ce pas?num_wheels
un attribut sur uncar
, alors qu'avec unOneToOneField
vous aurez à faire référence à vous-même.app_car
table de sorte qu'il a aussi lenum_wheels
champ, au lieu d'avoir levehicle_id
pointeur?Voulais juste ajouter quelque chose dont je n'ai pas vu dans d'autres réponses.
À la différence avec les classes python, nom du champ cacher est pas permis avec le modèle de l'héritage.
Par exemple, j'ai expérimenté des problèmes avec un cas d'utilisation comme suit:
J'ai eu un modèle héritant de django auth PermissionMixin:
Puis j'ai eu mon mixin qui, entre autres choses, j'ai voulu remplacer la
related_name
de lagroups
champ. Il était donc plus ou moins comme ceci:J'ai été en utilisant ce 2 mixin comme suit:
Donc oui, je m'attendais à ce que le travail, mais il n'a pas.
Mais le problème est plus grave que l'erreur que je recevais n'était pas pointant vers des modèles à tous, je n'avais aucune idée de ce qui allait mal.
Tout en essayant de résoudre ce je au hasard décidé de changer ma mixin et la convertir en un modèle abstrait mixin. L'erreur a changé à cela:
Comme vous pouvez le voir, cette erreur ne peut expliquer ce qui se passe.
C'était une énorme différence, à mon avis 🙂
La principale différence est la façon dont les tables de bases de données pour les modèles sont créés.
Si vous utiliser l'héritage sans
abstract = True
Django va créer un tableau distinct pour les deux parents et le modèle de l'enfant qui détiennent les champs définis dans chaque modèle.Si vous utilisez
abstract = True
pour la classe de base de Django ne fera que créer une table pour les classes qui héritent de la classe de base, même si les champs sont définis dans la classe de base ou de la classe qui hérite.Avantages et les inconvénients dépend de l'architecture de votre application.
Compte tenu de l'exemple suivant les modèles:
Si le
Publishable
classe n'est pas abstraite, Django va créer un tableau de publishables avec les colonnestitle
etdate
et des tables séparées pour lesBlogEntry
etImage
. L'avantage de cette solution est que vous êtes en mesure de requête sur tous publishables pour les champs définis dans le modèle de base, peu importe si elles sont entrées de blog ou des images. Mais donc Django aurez à faire des jointures, par exemple si vous effectuez des recherches pour les images...Si
Publishable
abstract = True
Django ne va pas créer une table pourPublishable
, mais uniquement pour les entrées de blog et les images, contenant tous les champs (également celles héritées). Ce serait pratique car pas de jointures seraient nécessaires pour une opération telle que obtenir.Voir aussi De Django reinhardt, de la documentation sur le modèle de l'héritage.
La principale différence est que lorsque vous héritent de la classe Utilisateur. Une version se comporte comme une simple classe, et l'autre se comportent comme un Django modeel.
Si vous héritez de la base "objet" version, votre Employé de classe sera une classe standard, et le prenom de ne pas faire partie d'une table de base de données. Vous ne pouvez pas créer un formulaire ou d'utiliser toute autre Django fonctionnalités avec elle.
Si vous héritez les modèles.Version du modèle, votre classe d'Employés auront toutes les méthodes de Django Modèle, et il héritera de la prenom champ comme un champ de base de données qui peut être utilisé dans un formulaire.
Selon la documentation, un Modèle Abstrait "fournit un moyen de factoriser les informations communes à l'Python niveau, tout en créant, d'une table de base de données par enfant modèle au niveau base de données."