Question

Dites, il y a une page qui a de nombreux blocs qui y sont associés. Et chaque bloc a besoin d'un rendu personnalisé, l'enregistrement et des données.

il est plus simple, du point de vue du code, pour définir les différentes classes (donc, modèles) pour chacun de ces modèles. Simplifiée comme suit:

class Page(models.Model):
    name = models.CharField(max_length=64)

class Block(models.Model):
    page = models.ForeignKey(Page)

    class Meta():
        abstract = True

class BlockType1(Block):

    other_data = models.CharField(max_length=32)

    def render(self):
        """Some "stuff" here """
        pass

class BlockType2(Block):

    other_data2 = models.CharField(max_length=32)

    def render(self):
        """Some "other stuff" here """
        pass

Mais,

  • Même avec ce code, je ne peux pas faire une requête comme page.block_set.all() pour obtenir tous les différents blocs, quel que soit le type de bloc.
  • La raison de ce qui précède est que, chaque modèle définit une table différente; Travailler autour de l'accomplir en utilisant un modèle de liaison et les clés étrangères génériques, peut résoudre le problème, mais il laisse encore des tables de base de données multiples requêtes par page.

Quelle serait la bonne façon de ce modèle? Peuvent les clés étrangères génériques (ou quelque chose d'autre) être utilisés d'une manière, pour stocker les données de préférence dans la même table de base de données, mais obtenir des paradigmes d'héritage.

Mise à jour:

Mon point était, Comment puis-je obtenir encore les paradigmes POO à travailler . En utilisant une même méthode avec tant ifs est pas ce que je voulais faire.

La meilleure solution, me semble, est de créer une catégorie distincte de python standard (de préférence dans un autre blocks.py), qui définit une sauvegarde qui enregistre les données et son « type » par instancier le même modèle. Ensuite, créez une étiquette de modèle et un filtre qui appelle le rendu, sauf, et d'autres méthodes basées sur le type de modèle.

Était-ce utile?

La solution

Ne modélise pas la page dans la base de données. Les pages sont une chose de présentation.

Première - et avant tout - obtenir les données droite

.

« Et chaque bloc a besoin d'un rendu personnalisé, l'enregistrement et des données. » Briser ce bas: vous avez des données uniques. Ignorer le « bloc » et « rendu » du point de vue du modèle. Il suffit de définir les données sans tenir compte de la présentation .

Sérieusement. Il suffit de définir les données dans le modèle sans aucune considération de la présentation ou déchirante ou quoi que ce soit d'autre. Obtenez le bon modèle de données.

Si vous confondez le modèle et la présentation, vous ne serez jamais rien de bien travailler. Et si vous obtenez à travailler, vous ne serez jamais en mesure d'étendre ou de le réutiliser.

Deuxième - seulement après le modèle de données est droite -. Vous pouvez activer la présentation

Vos « blocs » peut se faire simplement avec des balises HTML de <div> et une feuille de style. Essayez cette première. Après tout, le modèle fonctionne et est très simple. Ceci est juste HTML et CSS, distinct du modèle.

Vos « blocs » peuvent nécessiter des balises de modèle personnalisé pour créer plus complexe, HTML conditionnel. Essayez cette seconde.

Vos « blocs » peuvent - dans un cas extrême - être si complexe que vous devez écrire une fonction de vue spécialisée pour transformer plusieurs objets en HTML. Ceci est très, très rare. Vous ne devriez pas le faire jusqu'à ce que vous êtes sûr que vous ne pouvez pas le faire avec les balises de modèle.


Modifier.

"requête de différentes sources de données externes"

« classes simples séparés (pas de modèles) qui ont une méthode de sauvegarde, qui écrivent à la même table de base de données. »

Vous avez trois choses complètement différentes, sans lien, séparés.

  • Modèle. Le modèle persistant. Avec la méthode save(). Ceux-ci font très, très peu. Ils ont des attributs et quelques méthodes. Non « requête de différentes sources de données externes ». Non "rendu en HTML".

  • Sources de données externes. Ce sont des classes Python ordinaires qui acquièrent des données. Ces objets (1) obtenir des données externes et (2) créer des objets modèle. Et rien d'autre. Non « persistance ». Non "rendu en HTML".

  • Présentation. Ce sont des modèles ordinaires de Django qui présentent les objets du modèle. Aucune requête externe. Pas de persistance.

Autres conseils

Je viens de terminer un prototype de système qui a ce problème à la pelle: une base de classe de produits et environ 200 classes de détail qui varient énormément. Il y a beaucoup de situations dans lesquelles nous faisons des requêtes générales contre produit, mais veulent ensuite traiter les détails spécifiques à la sous-classe lors du rendu. Par exemple. obtenir tous les produits de fournisseur X, mais affichent des modèles légèrement différents pour chaque groupe d'une sous-classe spécifique.

J'ai ajouté des champs cachés pour un GenericForeignKey la classe de base et remplit automatiquement le content_type et object_id de la classe des enfants à sauver () temps. Lorsque nous avons un objet générique, on peut dire obj = prod.detail puis travailler directement avec l'objet de la sous-classe. A pris environ 20 lignes de code et il fonctionne très bien.

L'un Gotcha nous avons rencontré au cours des essais était que manage.py dumpdata suivie manage.py loaddata gardé jeter Integrity Errors. Il s'avère que c'est un problème bien connu et un correctif est prévu dans la version 1.2. Nous travaillons en utilisant les commandes MySQL pour vider / recharger l'ensemble de données de test.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top