Frage

Ich habe gerade getan Arbeit durch die Django-Tutorials zum zweiten Mal, und ich verstehe die Dinge viel klarer jetzt. Aber ich bin immer noch unklar, wie Anwendungen innerhalb einer Website miteinander in Wechselwirkung treten.

Zum Beispiel kann sagen, dass ich eine Blog-Anwendung zu schreiben (eine ziemlich beliebte Aktivität, scheinbar). Blog-Posts und Kommentare dazu neigen, zusammen zu gehen, und doch sind sie deutlich genug, dass sie in separate Anwendungen gebaut werden sollten, da die allgemeine Philosophie der Djano Entwicklung.

Betrachten Sie das folgende Beispiel. In Wirklichkeit würde ich nicht wirklich schreiben Kommentar selbst app, so gut Code für das bereits auf dem Netz vorhanden ist, aber dies ist für die Demonstration / Übungszwecken:

mysite / Blog / models.py

from django.db import models

class post(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=200)
    content = models.TextField()

mysite / Kommentare / models.py

from django.db import models
from mysite.blog.models import post

class comment(models.Model):
    id = models.AutoField()
    post = models.ForeignKey(post)
    author = models.CharField(max_length=200)
    text = models.TextField()

Ist das, was ich oben geschrieben hätte, ein Modell aus einer anderen Anwendung importieren und als Fremdschlüssel einstellen, wie Django apps interagieren? Oder gibt es eine andere / bessere Methode für die Anwendungen, die eine Website umfassen interagieren?

Aktualisieren
Gemäß der Empfehlung in einer Antwort, lese ich in der Dokumentation zu contrib.contenttypes. Wenn ich das richtig gerade lese, könnte ich mein Beispiel Kommentar App wie folgt umschreiben:

from django.db import models  
from django.contrib.contenttypes.models import ContentType
from django.contrib.contentypes import generic

class comment(models.Model):  
    id = models.AutoField()  
    author = models.CharField(max_length=200)  
    text = models.TextField()  
    content_type = models.ForeignKey(ContentType)  
    content_object = generic.GenericForeignKey(content_type, id)  

Wäre das richtig sein?

War es hilfreich?

Lösung

Werfen Sie einen Blick auf Djangos integrierten Content Rahmen :

django.contrib.contenttypes

Es ermöglicht Ihnen, Ihre Anwendungen als Stand-alone-Geräte zu entwickeln. Dies ist, was die django-Entwickler verwendet Djangos integrierten in Kommentar Rahmen um einen Kommentar zu jedem Modell in Ihrem Projekt zu befestigen.

Zum Beispiel, wenn Sie einige Inhalte zum Gegenstand haben, die Sie wollen „anhänge“ auf andere Inhaltsobjekten verschiedenen Typen, wie so dass jeder Benutzer einen „Favoriten“ Stern auf einem Blog-Post, Bild zu verlassen, oder Benutzerprofil, Sie ein Favorite Modell mit einem generischer Beziehung Feld kann erstellen etwa so:

from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class Favorite(models.Model):
    user = models.ForeignKey(User)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

Auf diese Weise können Sie einen Favorite Stern von jedem Benutzer zu jedem Modell in Ihrem Projekt hinzufügen. Wenn Sie API-Zugriff über das Empfängermodell Klasse hinzufügen möchten, können Sie entweder fügen Sie ein Reverse generische Beziehung Feld auf dem Empfänger-Modell (auch wenn dies „Kopplung“ die beiden Modelle würde, was Sie sagten, Sie vermeiden wollen), oder tut die Lookup durch das Favorite Modell mit dem content_type und object_id des Empfängers Beispiel finden Sie in der für ein Beispiel.

Andere Tipps

„Ist das, was ich oben geschrieben hätte, ein Modell aus einer anderen Anwendung importieren und als Fremdschlüssel einstellen, wie Django apps interagieren?“

Ja. Funktioniert bei mir.

Wir haben etwa 10 Anwendungen, die hin und her untereinander leihen.

Dies führt zu einer Art von Abhängigkeit in unserer Einheit Testskript.

Es sieht wie folgt aus.

  • "Eigentum". Wir haben eine einfache Datenbesitz-Anwendung, die einige grundlegende Eigentums Konzepte definiert, die anderen Anwendungen abhängig sind. Es gibt ein paar einfache Tabellen hier.

  • "Ding". [Nicht der richtige Name]. Unsere Sache Anwendung hat Datenelemente von verschiedenen Benutzergruppen gehören. Es gibt tatsächlich mehrere komplexe Tabellen das Modell für diese App. Es kommt darauf an "ownership".

  • "Tabellen". [Nicht der richtige Name]. Einige unserer Benutzer erstellen ziemlich komplexe Offline-Modelle (wahrscheinlich mit Tabellen) und laden Sie die Ergebnisse dieser Modellierung in „Tabellen“. Dies hat einen Cluster von ziemlich komplexen Tabellen. Es kommt darauf an "ownership".

  • "Ergebnis". [Nicht der richtige Name]. Unsere Ergebnisse sind auf die Dinge beruhen, die Eigentümer haben. Die Ergebnisse basieren auf Dinge und Tabellen, und Antworten auf Kundenanfragen. Dies ist nicht zu komplex, vielleicht nur zwei oder drei Kerne Tabellen. Es kommt darauf an „Dinge“ und „table“. Nein, es nicht vollständig stand-alone. Es ist jedoch zu mehr Veränderungen unterworfen als die anderen Dinge, von denen es abhängt. Deshalb ist es getrennt.

  • "Verarbeitung". Wir planen und große Batch-Jobs überwachen. Dies ist in dieser Anwendung. Es ist wirklich generisch und kann in vielfältiger Weise eingesetzt werden. Es völlig allein steht.

  • "Willkommen". Wir haben ein „welcome“ App, die eine Reihe von meist statischen Seiten präsentiert. Dies hat nicht zu viele Tische. Aber es ist auf seine zweite Inkarnation, weil die ersten zu komplex war. Es völlig allein steht.

Die einzige Beziehung zwischen den abhängigen Anwendungen sind einige Tabellennamen. Solange wir diese Tabellen (und ihre Schlüssel) erhalten wir andere Anwendungen neu anordnen können, wie wir sehen, passen.

Es ist nichts falsch (imho) mit der Herstellung einiger App auf einem anderen abhängig. Immerhin Apps sind nur Operationen auf einer Reihe von Modellen. Sie müssen nur immer bewusst sein, welche App hängt davon ab, welche App (ich glaube, dass eine Abhängigkeit Karte nennen könnte).

Sie können die lose Kopplung mit dem Rahmen Content erreichen. Es ermöglicht eine App truely portable / steckbare noch noch mit anderen Anwendungen integriert werden.

Ich schrieb einen Kommentar app (ja, ich wieder das Rad erfunden), kann diese in eine andere Anwendung integriert werden, mit ein paar Zeilen in der Vorlage der Seite, auf Kommentare sollten (unter Verwendung von benutzerdefinierten Tags) gebucht werden.

Sagen Sie bitte ein Modell „Faden“ soll in jedes andere Modell steckbar sein. Die Idee ist, e allgemeine Fremdschlüssel (siehe django Dokumentation über die), und schreiben Sie eine kleine Funktion zu erstellen, die jedes Objekt nimmt und gibt einen „Faden“, um es entsprechend (oder erstellt, falls erforderlich), und einen eigenen Template-Tag schrieb, dass diese Funktionalität verwendet, zB {% get_thread for arbitrary_object as thread %}. Alle Stellen werden auf ein Gewinde zusammen, die mit dem Objekt in Beziehung steht, die von jeder Art sein kann.

Sie können als eine Art eines Proxy des „Faden“ Objekts denken, so stattdessen einen Beitrag zu müssen, einen bestimmten „Artikel“ oder „Blog-Post“ in Beziehung gesetzt werden, ist es nur zu einem Faden zusammen, die abstrakt ist in gewissem Sinne, was ist ist ein Thread? Es ist nur eine Sammlung von Beiträgen. Der Faden läßt sich dann unabhängig von seiner Art auf jedes Objekt bezogen werden. (Obwohl es mehr als das der Fall ist, könnte es zusätzliche Informationen enthalten wie erlaubt / disallowing Anon. Beiträge, Schließen / Öffnen Kommentare auf der Seite, etc ..)

Bearbeiten

Hier ist, wie Sie einen allgemeinen Fremdschlüssel mit dem Inhaltstyp Rahmen schaffen können:

from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType

class Thread( models.Model ):
    object_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    object = generic.GenericForeignKey('object_type', 'object_id')

Sie können machen es „transparent“ durch die implizite „gemeinsame“ Schnittstelle zu nutzen, dass alle Objekte django übernimmt implementieren ..

    #inside the Thread class:
    def __unicode__(self):
        return unicode(self.object)
    def get_absolute_url(self):
        return self.object.get_absolute_url()

Der Code scheint korrekt. Ich würde den Posten halten und den Kommentar in einem Blog App though. Ich sage nicht, das ist die Django Art und Weise, aber diese Modelle sind nah genug in der gleichen App zu sein.

Wie Teilen Sie das Projekt

Ich würde eine App trennen, wenn;

  • Ich plane es resuable zu entwerfen. (Und versuchen, lose Kopplung)
  • (für große Projekte) Es besteht aus einem Hauptteil des Projektes.

Auf der anderen Seite; viele kleine Anwendungen, die (wie eine App mit einem einzigen Modell und zwei Ansichten) ist schwer zu lesen und IMHO zu halten.

Wie Apps Interact Sollte

Dies ist abhängig von der Art des Projektes und die Art der App wieder. wenn eine App zum Beispiel ist implizit abhängig von anderen (dh nicht generisch) importieren und Referenzen von anderen App akzeptabel ist. In diesem Fall könnte die zweite App allein installiert werden, aber die ersten braucht man das Vorhandensein der zweiten.

Wenn Sie eine App sehr wiederverwendbar und generisch, wie zum Beispiel eine Kommentierung App machen wollen, müssen Sie möglicherweise einige Setup-Mechanismus integrieren. Vielleicht sind einige neue Einstellungen oder zusätzliche URL-Konfiguration oder eine Sonderrichtlinie / Methode auf Ihre Modelle ... django.contrib.admin ist ein gutes Beispiel dafür.

Apps sollte nicht in Wechselwirkung treten, wenn es aber nicht notwendig ist. Designing Anwendungen unnötig Kopplung zu vermeiden, ist sehr nützlich. Es verbessert die Flexibilität Ihrer App und macht sie besser verwaltbar (aber möglicherweise mit höheren Kosten bei der Integration).

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