Wie kann ich jedes Objekt / Modell von einem anderen Django-Modell agnostisch verknüpfen?

Ich schreibe ein einfaches CMS basierend auf Django. Die meisten Content-Management-Systeme verlassen sich auf eine feste Seite, auf einer festen URL, mit einer Vorlage, die eine oder mehrere bearbeitbare Regionen hat. Um eine editierbare Region zu haben, benötigen Sie eine Seite. Für das System, um herauszufinden, welche Seite, benötigen Sie die URL.

Das Problem kommt, wenn du dich nicht mehr mit "Seiten" beschäftigst (sei die FlatPages-Seiten oder etwas anderes), sondern eher Instanzen aus einem anderen Modell. Zum Beispiel, wenn ich ein Modell von Produkten habe, möchte ich eine Detail-Seite erstellen, die mehrere bearbeitbare Regionen innerhalb hat.

Ich könnte diese Regionen in das Modell bauen, aber in meinem Fall gibt es mehrere Modelle und ist eine Menge Abweichung in wieviel Daten, die ich zeigen möchte.

Deshalb möchte ich das CMS auf Template-Ebene aufbauen und spezifizieren, was ein Block (eine editierbare Region) auf der Instanz von "page" oder dem verwendeten Modell basiert.

Ich hatte die Idee, dass ich vielleicht kundenspezifische Vorlagen-Tags auf der Seite wie folgt abgeben könnte:

{% block unique_object "unique placeholder name" %} 

Und das würde einen "Block" finden, der auf den beiden vorgebrachten Argumenten basiert. Ein Beispiel:

 <h1>{{ product_instance.name }}</h1> {% block product_instance "detail: product short description" %} {% block product_instance "detail: product video" %} {% block product_instance "detail: product long description" %} 

Klingt schlau, richtig? Nun, das Problem, das ich laufe, ist, wie kann ich einen "Schlüssel" für eine Zone erstellen, damit ich den richtigen Block ausziehen kann? Ich werde mit einem völlig unbekannten Objekt umgehen (es könnte ein "Seiten" -Objekt, eine URL, eine Modellinstanz, alles sein – es könnte sogar ein Boot sein </fg> ).

Andere Django-Mikroanwendungen müssen dies tun. Sie können alles mit django-tagging, richtig? Ich habe versucht zu verstehen, wie das funktioniert, aber ich zeichne Leerzeichen.

Also, erstmal, bin ich verrückt? Und wenn ich nicht nehme, und das sieht aus wie eine relativ gesunde Idee zu überreden, wie soll ich über eine Verknüpfung eines Objekts + Strings mit einer Block / editierbaren Region gehen?

Hinweis: Die Bearbeitung erfolgt auf der Seite, so dass es keine wirkliche Frage gibt, wenn die Benutzer die Zonen bearbeiten können. Ich werde in der Admin keinen Reverse-Mumbo-Jumbo machen müssen. Mein letzter Traum ist es, ein drittes Argument zu geben, um festzulegen, welche Art von Inhaltsbereich dies ist (Text, Bild, Video, etc.). Wenn Sie irgendwelche Kommentare zu irgendwelchen von diesem haben, bin ich glücklich, sie zu lesen!

3 Solutions collect form web for “Wie kann ich jedes Objekt / Modell von einem anderen Django-Modell agnostisch verknüpfen?”

Django-Tagging verwendet Djangos Content – Typen- Framework. Die Docs machen eine viel bessere Arbeit zu erklären, als ich kann, aber die einfachste Beschreibung davon wäre "generischen Fremdschlüssel, der auf jedes andere Modell zeigen kann."

Das ist vielleicht das, was du suchst, aber aus deiner Beschreibung klingt es auch so, als würdest du etwas ganz Ähnliches mit einigen anderen existierenden Projekten machen:

  • Django-flatblocks ("… wirkt wie django.contrib.flatpages aber für Teile einer Seite, wie eine editierbare Hilfebox, die du neben dem Hauptinhalt sehen möchtest.")

  • Django-better-chunks ("Denken Sie an es als Flatpages für kleine Bits von wiederverwendbaren Inhalten, die Sie vielleicht in Ihre Vorlagen einfügen und von der Admin-Schnittstelle verwalten möchten.")

und so weiter. Wenn diese ähnlich sind, dann machen sie einen guten Ausgangspunkt für Sie.

Sie wollen eine Möglichkeit, einige objektspezifische Inhalte auf einer generischen Vorlage anzuzeigen, bei einem bestimmten Objekt, richtig?

Um sowohl Modelle als auch andere Gegenstände zu unterstützen, brauchen wir zwei Zwischenmodelle; Eins, um Strings zu behandeln, und man, um Modelle zu handhaben. Wir könnten es mit einem Modell machen, aber das ist weniger performant. Diese Modelle werden die Verbindung zwischen Inhalt und String / Modell zur Verfügung stellen.

 from django.db import models from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic CONTENT_TYPE_CHOICES = ( ("video", "Video"), ("text", "Text"), ("image", "Image"), ) def _get_template(name, type): "Returns a list of templates to load given a name and a type" return ["%s_%s.html" % (type, name), "%s.html" % name, "%s.html" % type] class ModelContentLink(models.Model): key = models.CharField(max_length=255) # Or whatever you find appropriate type = models.CharField(max_length=31, choices= CONTENT_TYPE_CHOICES) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() object = generic.GenericForeignKey('content_type', 'object_id') def get_template(self): model_name = self.object.__class__.__name__.lower() return _get_template(model_name, self.type) class StringContentLink(models.Model): key = models.CharField(max_length=255) # Or whatever length you find appropriate type = models.CharField(max_length=31, choices= CONTENT_TYPE_CHOICES) content = models.TextField() def get_template(self): return _get_template(self.content, self.type) 

Nun ist alles, was wir brauchen, ein Template-Tag, um diese zu packen, und dann versuchen, die Vorlagen zu laden, die durch die Methode 'get_template () der Modelle gegeben werden. Ich bin ein bisschen gedrückt auf Zeit, also werde ich es verlassen und dies in ~ 1 Stunde aktualisieren. Lassen Sie mich wissen, wenn Sie denken, dass dieser Ansatz gut scheint.

Es ist ziemlich einfach, das contenttypes Framework zu verwenden, um die Lookup-Strategie zu implementieren, die du beschreibst:

 class Block(models.Model): content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() object = generic.GenericForeignKey() # not actually used here, but may be handy key = models.CharField(max_length=255) ... other fields ... class Meta: unique_together = ('content_type', 'object_id', 'key') def lookup_block(object, key): return Block.objects.get(content_type=ContentType.objects.get_for_model(object), object_id=object.pk, key=key) @register.simple_tag def block(object, key) block = lookup_block(object, key) ... generate template content using 'block' ... 

Man muss sich bewusst sein, dass man das object im Block.objects.get Aufruf verwenden kann, da es sich nicht um ein echtes Datenbankfeld handelt. Sie müssen content_type und object_id .

Ich habe das Modell Block , aber wenn man einige Fälle hat, in denen mehr als ein einziges (object, key) Tupel auf denselben Block abbildet, kann es in der Tat ein Zwischenmodell sein, das selbst einen ForeignKey zu deinem aktuellen ForeignKey oder zum Passendes Modell in einer Helfer-App wie die, die Van Gale erwähnt hat.

  • Letzte Rekord in django Modelle Datenbank
  • Speichern von Wiki-Revisionen auf Google App Engine / Django - Ändern dieser vorhandenen Code
  • Django sagt die "id darf nicht NULL" aber warum ist es?
  • Django-Modell mit dynamischen Attributen
  • Benutzerdefiniertes Django MultilingualTextField Modellfeld
  • Löschen eines untergeordneten Objekts in der Django-Datenbank
  • Fremdschlüsselzugriff
  • Manager ist nicht über `Modell` Instanzen zugänglich
  • Django eine App ein Modell mehrere Datenbanken
  • Überschreiben Sie djangos Objekt.all () mit den Anforderungsdaten
  • Wie kann ich Stadt, Region, Land aus einer URL extrahieren? Django
  • Python ist die beste Programmiersprache der Welt.