Anfänger: Der Versuch, zu verstehen, wie Anwendungen interagieren in Django

stimmen
28

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

Zum Beispiel kann sagen, ich habe 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 sollen, wie 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 zu interagieren?

Aktualisieren
Pro Empfehlung in einer Antwort, lese ich in der Dokumentation zu contrib.contenttypes. Wenn ich das richtig bin gelesen hatte , konnte 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?

Veröffentlicht am 09/12/2008 um 18:25
quelle vom benutzer
In anderen Sprachen...                            


4 antworten

stimmen
21

Werfen Sie einen Blick auf Djangos Einbau- Content Rahmen :

django.contrib.contenttypes

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

Zum Beispiel, wenn Sie einige Inhalte zum Gegenstand haben , die Sie andere Inhaltsobjekte verschiedenen Typen „anhänge“ wollen, wie so dass jeder Benutzer einen „Favoriten“ Stern auf einer Blog - Post, ein Bild oder Benutzerprofil verlassen, können Sie eine erstellen FavoriteModell mit einem generischen Beziehung Feld wie folgt:

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 hinzufügen FavoriteStern von jedem Benutzer zu jedem Modell in Ihrem Projekt. Wenn Sie API - Zugriff über das Empfängermodell Klasse hinzufügen mögen , können Sie entweder eine hinzufügen Reverse - generic Beziehung Feld auf dem Empfänger - Modell (auch wenn dies „Kopplung“ die beiden Modelle würde, was Sie sagen , Sie vermeiden wollen) oder die Lookup durch das FavoriteModell mit der content_typeund object_idder Empfänger - Instanz finden Sie in den offiziellen Dokumente für ein Beispiel.

Beantwortet am 09/12/2008 um 19:01
quelle vom benutzer

stimmen
3

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 lose Kopplung mit dem Content Rahmen erreichen. Es ermöglicht eine App truely portable / steckbare noch noch mit anderen Anwendungen integriert werden.

Ich schrieb einen Kommentar app (ja, ich das Rad neu erfunden), das in jede andere Anwendung integriert werden kann, 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 nutzt diese Funktionalität, zum Beispiel {% 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 in einem gewissen Sinne abstrakt was 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 es „transparent“ durch Ausnutzen der impliziten „gemeinsame“ Schnittstelle machen mehr, die django alle Objekte implementieren übernimmt ..

    #inside the Thread class:
    def __unicode__(self):
        return unicode(self.object)
    def get_absolute_url(self):
        return self.object.get_absolute_url()
Beantwortet am 09/12/2008 um 19:35
quelle vom benutzer

stimmen
3

„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 aus wie das.

  • "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.

  • "wird bearbeitet". 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 steht ganz allein.

  • "herzlich 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 steht ganz allein.

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

Beantwortet am 09/12/2008 um 19:06
quelle vom benutzer

stimmen
2

Ihr Code scheint richtig. Ich würde den Posten halten und den Kommentar in einem Blog obwohl App. Ich sage nicht , das ist der Django Weg, aber diese Modelle sind nah genug in der gleichen App zu sein.

Wie das Projekt Teilen

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.

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

Wie Apps Sollte Interact

Dies hängt 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.administ ein gutes Beispiel dafür.

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

Beantwortet am 09/12/2008 um 18:45
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more