Frage

Sag mal, gibt es eine Seite, die viele Blöcke, die mit ihm hat. Und jeder Block muss benutzerdefinierten Rendering, Speicher und Daten.

Einfachstes ist es, aus dem Code Sicht verschiedene Klassen zu definieren (und somit Modelle) für jedes dieser Modelle. Vereinfacht wie folgt:

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

Aber dann,

  • Auch mit diesem Code, ich kann nicht eine Abfrage wie page.block_set.all() tut alle die verschiedenen Blöcke zu erhalten, unabhängig von dem Blocktyp.
  • Der Grund für die obige ist, dass jedes Modell eine andere Tabelle definiert; Arbeiten um zu erreichen, es ein Verbindungsmodell und generische Fremdschlüssel verwenden, kann das Problem lösen, aber es bleibt immer noch mehrere Datenbanktabellen Abfragen pro Seite.

Was wäre der richtige Weg, es zu modellieren? Können die allgemeinen Fremdschlüssel (oder etwas anderes) in irgendeine Weise verwendet werden, um die Daten in der gleichen Datenbanktabelle vorzugsweise zu speichern, noch Vererbungs Paradigmen erreichen.

Update:

Mein Punkt war, Wie kann ich immer noch die OOP Paradigmen an der Arbeit . ein nach demselben Verfahren mit so viele ifs ist nicht, was ich tun wollte.

Die beste Lösung, scheint mir, ist separate Standard-Python-Klasse zu erstellen (vorzugsweise in einem anderen blocks.py), das definiert, ein Spar der speichert die Daten und dessen „Typen“ durch das gleiche Modell instanziieren. Dann einen Template-Tag erstellen und einen Filter, der die Anrufe machen, speichern und andere Methoden basierend auf die Art des Modells.

War es hilfreich?

Lösung

Do die Seite nicht in der Datenbank modellieren. Seiten sind eine Präsentation Sache.

Erste - und vor allem -. Die Daten richtig machen

„Und jeder Block Bedürfnisse individuelle Rendering, Speichern und Daten.“ Brechen Sie diese nach unten: Sie einzigartige Daten. Ignorieren den „Block“ und „rendering“ aus einem Modell Perspektive. Definieren Sie einfach die Daten ohne Rücksicht auf die Präsentation .

Im Ernst. Definieren Sie einfach die Daten im Modell ohne Berücksichtigung der Präsentation oder Zerreißen oder irgendetwas anderes. Holen Sie sich das Datenmodell richtig.

Wenn Sie das Modell und die Präsentation zu verwirren, werden Sie nie gut etwas an der Arbeit. Und wenn Sie es an der Arbeit zu tun bekommen, werden Sie nie in der Lage sein, um es zu verlängern oder wiederverwendet werden.

Zweite - erst nach dem Datenmodell ist rechts -. Sie Präsentation verwandelt

Ihre „Blöcke“ können einfach mit HTML-Tags <div> und einem Stylesheet erfolgen. Versuchen Sie, dass zuerst. Schließlich arbeitet das Modell und ist sehr einfach. Dies ist nur HTML und CSS, aus dem Modell trennen.

Ihre „Blöcke“ können benutzerdefinierte Vorlagen-Tags erfordern komplexere, bedingte HTML zu erstellen. Versuchen Sie, dass die zweite.

Ihre „Blöcke“ können - im Extremfall - so komplex sein, dass Sie eine spezielle Ansicht Funktion schreiben, müssen mehrere Objekte in HTML zu umwandeln. Das ist sehr, sehr selten. Sie sollten dies nicht tun, bis Sie sicher sind, dass Sie diese mit Template-Tags nicht tun können.


Bearbeiten.

"Abfrage verschiedene externe Datenquellen"

„getrennte einfache Klassen (nicht Modelle), die eine Speichermethode hat, dass Schreiben auf die gleiche Datenbanktabelle.“

Sie haben drei völlig verschiedene, unabhängige, getrennte Dinge.

  • Modell. Das anhaltende Modell. Mit dem save() Verfahren. Dies tut sehr, sehr wenig. Sie haben Attribute und ein paar Methoden. Keine „Abfrage verschiedene externe Datenquellen“. Nein "Rendern in HTML".

  • Externe Datenquellen. Dies sind gewöhnliche Python-Klassen, die acquire Daten. Diese Objekte (1) erhalten externe Daten und (2) erstellen Modellobjekte. Und sonst nichts. Nein „Beharrlichkeit“. Nein "Rendern in HTML".

  • Präsentation. Dies sind gewöhnliche Django-Vorlagen, die die Modell-Objekte präsentieren. Keine externe Abfrage. Keine Persistenz.

Andere Tipps

Ich habe gerade einen Prototyp des Systems, das dieses Problem in den Spaten hat: eine Basis Produktklasse und etwa 200 Detail-Klassen, die stark variieren. Es gibt viele Situationen, in denen wir allgemeine Fragen gegen Produkt tun, wollen aber dann mit den Subklassen-spezifischen Details während des Renderings beschäftigen. Z.B. erhält alle Produkte von Herstellern X, aber Display mit leicht unterschiedlichen Vorlagen für jede Gruppe von einer bestimmten Unterklasse.

habe ich Felder versteckt für eine GenericForeignKey die Basisklasse und auto-füllt die content_type & object_id des Kindes Klasse an save () Zeit. Wenn wir ein generisches Produkt Objekt haben, können wir obj = prod.detail sagen und dann mit dem Unterklasse-Objekt direkt arbeiten. Dauerte etwa 20 Zeilen Code und es funktioniert super.

Die eine gotcha liefen wir in während der Prüfung, dass manage.py dumpdata von manage.py loaddata gefolgt war Integrity Errors gehalten zu werfen. Stellt sich heraus, das ist ein bekanntes Problem und ein Update in der Version 1.2 erwartet. Wir arbeiten um ihn herum durch mysql-Befehle dump / laden Sie die Testdatei.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top