<div dir="ltr">Hallo Sascha,<div><br></div><div>bei Django-Apps muss man unterscheiden zwischen Apps die nur im Kontext eines bestimmten Django-Projektes Sinn ergeben und sogenannten Reusable Apps die quasi Plug & Play in beliebige Django-Projekte integriert werden können.</div><div><br></div><div>Eine Reusable App sollte möglichst wenig Annahmen über das Django-Projekt machen. Allerdings ist es m.E. durchaus üblich dass eine Reusable App voraussetzt dass das Projekt bestimmte andere Apps verwendet, wie z.B. Sessions und eben die standardmäßigen Mechanismen zur Authentifizierung (also die App django.contrib.auth). Nach meiner Erfahrung sind Reusable Apps (die auch wirklich reusable sind) eher die Ausnahme. Wenn man vorhat eine Django-App zunächst ausschließlich als Teil eines Django-Projektes zu verwenden macht es nach meiner Erfahrung wenig Sinn diese als Reusable App in einem eigenständigen Python-Package zu entwickeln. Dadurch dass Reusable Apps schon im Django-Tutorial erklärt werden wird hier vielleich ein falsches Bild vermittelt.</div><div><br></div><div>Für Relationen zum User-Modell schlägt die Django-Dokumentation folgenden Ansatz vor:</div><div><br></div>from django.conf import settings<br>from django.db import models<br><br>class Article(models.Model):<br>    author = models.ForeignKey(<br>        settings.AUTH_USER_MODEL,<br>        on_delete=models.CASCADE,<br>    )<br><br>Siehe <a href="https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#reusable-apps-and-auth-user-model">https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#reusable-apps-and-auth-user-model</a><br><br>Ausserdem gibt es noch die Möglichkeit generische Relationen anzulegen. Damit kannst du z.B. eine (Reusable-)Tagging-App erstellen, die es erlaubt Tags an beliebige Models anzuhängen. Siehe <a href="https://docs.djangoproject.com/en/1.10/ref/contrib/contenttypes/">https://docs.djangoproject.com/en/1.10/ref/contrib/contenttypes/</a><div><div><br class="gmail-Apple-interchange-newline">Je nach Anwendungsfall ist es vielleicht ausreichend die Apps in den Templates zu verknüpfen. Anstatt in der View der Blog-App mit reverse eine URL zur Chat-App zu erzeugen und diese im Template-Context zu übergeben wird die URL im Template erzeugt. Das Template kann dabei auf Projekt-Ebene liegen, somit muss die Blog-App nichts von der Chat-App wissen.</div><div><div><br></div><div>Wenn das nicht ausreicht kann man sich beliebig komplizierte Plugin und Dependency Injection Mechanismen ausdenken, aber man sollte sich wirklich gut überlegen ob der Aufwand gerechtfertigt ist. Eine lose Koppelung ist sicher erstrebenswert, sollte aber nicht zum Selbstzweck verkommen.</div><div><br></div><div>Meines Erachtens ist es vollkommen legitim dass die einzelnen Apps eines Projektes voneinander abhängen. Im Idealfall sind diese Abhängigkeiten nicht zirkulär, aber manchmal lässt sich auch das nicht vermeiden.</div></div></div><div><br></div><div>Viele Grüße,</div><div>Daniel</div></div><div class="gmail_extra"><br><div class="gmail_quote">2017-02-18 12:46 GMT+01:00 Klaus Bremer <span dir="ltr"><<a href="mailto:klaus.bremer@bmcct.de" target="_blank">klaus.bremer@bmcct.de</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Hallo Sascha,<div><br></div><div>nein, Du hast keinen Denkfehler. Ab dem Augenblick, wo Du applikationsübergreifende Relationen anlegst (also einen ForeignKey auf ein Model einer anderen Applikation), ist es in django mit dem Loose Coupling vorbei. Loose Coupling bezieht sich in der Praxis eher auf die Verbindung zwischen URLs und Views. </div><div><br></div><div>Als Lektüre möchte ich Dir <a href="https://www.twoscoopspress.com/" target="_blank">https://www.<wbr>twoscoopspress.com/</a> empfehlen.</div><div>Dort findest Du jede Menge nützliche Informationen.</div><div><br></div><div> </div><div>Gruß</div><span class="HOEnZb"><font color="#888888"><div>Klaus</div></font></span><div><div class="h5"><div><br></div><div><br></div><div><br></div><div><br><div><blockquote type="cite"><div>Am 18.02.2017 um 11:56 schrieb Sascha Zantis <<a href="mailto:sascha.zantis@rwth-aachen.de" target="_blank">sascha.zantis@rwth-aachen.de</a>><wbr>:</div><br class="m_445348010731111430Apple-interchange-newline"><div><div>Hallo zusammen,<br><br>wie aus dem Subject ersichtlich ist, habe ich eine Frage zu Django. Da ich es aber von mehreren Mailinglisten kenne, dass es gerne gesehen ist, wenn sich neue User kurz vorstellen, mache ich das einfach mal.<br><br>Ich programmiere seit einigen Jahren (2008 oder 2009) ziemlich viel und sehr gerne Python und arbeite seit etwa 2.5 Jahren vermehrt im Bereich Webentwicklung, also nicht Python-only sondern eben auch mit PHP, Javascript und so weiter. Ich habe schon ein paar kleine bis mittelgroße Applikationen mit Flask und Pyramid umgesetzt, kenne mich auch ein bisschen in Ruby on Rails und so weiter aus. Vielleicht schaffe ich es ja in den nächsten Monaten mal zu eurem Stammtisch, das hatte ich mir eigentlich schon länger vorgenommen, Aachen selber hat ja offensichtlich keine eigene Python-Community.<br><br>Einführend zu meiner Frage: Ich arbeite mich gerade privat in Django ein mit dem Ziel, dieses Framework im Laufe des Jahres auch beruflich einzusetzen. Das offizielle Tutorial habe ich mittlerweile durch und weil noch ein paar Fragen offen geblieben sind, habe ich mir auch noch <a href="http://djangobook.com" target="_blank">http://djangobook.com</a> vorgenommen, bevor ich dann (nachdem ich mir noch ein Javascript-Framework angesehen habe, das ich nutzen möchte) mal eine "richtige" Applikation entwerfe. Zu der Frage habe ich bisher noch keine wirklich brauchbaren Antworten gefunden, vielleicht habe ich aber auch einen Denkfehler oder beachte irgendetwas Essentielles nicht.<br><br>Das Konzept des Loose Coupling, das auch auf Django-Apps zutrifft bedeutet ja in dem Kontext, dass jede App mehr oder weniger als standalone Paket zu betrachten ist und unabhängig von anderen Apps in verschiedenen Django-Applikationen nutzbar ist. Die Kopplung findet dann über die Projekt-settings.py und die Projekt-urls.py statt, die App wird dort installiert und an eine Route gemountet. Innerhalb der App werden dann Model, Templates usw. implementiert, die nur für diese App relevant sind.<br><br>Wenn ich nun nicht mehr nur eine Funktionalität in meinem Django-Projekt abbilden möchte, sondern mehrere, die aber gemeinsame Models verwenden sollen, stehe ich aktuell ein bisschen auf dem Schlauch. Ein fiktives Beispielprojekt könnte etwa so aussehen:<br><br>project:<br>  - blog<br>  - chat<br>  - diary<br>  - user<br><br>Auf dieser Seite könnten User bloggen, chatten und ein Tagebuch führen. Das Tagebuch wäre natürlich nicht öffentlich, Chats könnten wie auch immer aussehen. Alle Apps würden User-Funktionalität brauchen, die user-app würde auch Login, Registrierung, Profilseite usw. anzeigen und die gewohnte Funktionalität zur Userverwaltung anbieten.<br><br>Ich würde aber auch wollen, dass ich aus der Blog-Applikation auf den Chat zugreifen kann und im Chat würde ich auch gerne per User direkt ansprechen (Mit Autocompletion) oder auf Blogseiten verlinken (Vielleicht auch mit Autocompletion, um die Verbindung zu zeigen). Außerdem sollte es theoretisch möglich sein, dass ich alle Applikationen komplett einzeln installiere, ohne dass ich die users-Applikation dazu installieren muss.<br><br>Ein naiver Ansatz, der zwar die Applikationen verbindet, aber das Problem der Separierung nicht löst, wäre so etwas wie<br><br>---<br><br>from django.db import models<br>from user.models import User<br><br><br>class Diary(models.Model):<br>    …<br>    owner = models.ForeignKey(User)<br><br>---<br><br>Das Problem hierbei wäre, sobald meine User-Applikation nicht installiert ist, funktioniert das Ganze nicht. Dasselbe Problem würde auftreten, wenn ich in einer Blog-View Chat-Funktionalität aufrufen wollen würde, entweder über Routen oder sowas wie<br><br>HttpResponseRedirect(reverse('<wbr>chat:display_group_chat', args=(<a href="http://chat.id" target="_blank">chat.id</a>,)))<br><br>Sobald chat nicht installiert ist, funktioniert das nicht mehr.<br><br>Bevor ich jetzt anfange, mir Gedanken darum zu machen, wie ich das selber löse, einen Ansatz hatte ich mir schon überlegt:<br><br>diary bekommt eine eigene user.py und in models.py würde dann sowas passieren wie:<br><br>---<br><br>from django.db import models<br>if is_installed(user_application)<wbr>:<br>    from user.models import User<br>else:<br>    from .user import User<br><br><br>class Diary(models.Model):<br>    …<br>    owner = models.ForeignKey(User)<br>---<br><br>wollte ich mich mal erkundigen, ob es da vielleicht einen einfachen "Django-Way" gibt, der das Problem für mich löst oder ob ich da generell einen Denkfehler habe.<br><br><br>Viele Grüße<br>Sascha<br>______________________________<wbr>__________<br><br>Diese Mail erhalten Sie ueber die Mailingliste python-users der Universitaet zu Koeln<br>Nachrichten an: <a href="mailto:python-users@uni-koeln.de" target="_blank">python-users@uni-koeln.de</a><br>Abonnement und Benutzereinstellungen: <a href="https://lists.uni-koeln.de/mailman/listinfo/python-users" target="_blank">https://lists.uni-koeln.de/<wbr>mailman/listinfo/python-users</a><br>Listenarchiv: <a href="http://pycologne.de/mlsearch.html" target="_blank">http://pycologne.de/mlsearch.<wbr>html</a><br><br>pyCologne Homepage: <a href="http://pycologne.de/" target="_blank">http://pycologne.de/</a><br></div></div></blockquote></div><br></div></div></div></div><br>______________________________<wbr>__________<br>
<br>
Diese Mail erhalten Sie ueber die Mailingliste python-users der Universitaet zu Koeln<br>
Nachrichten an: <a href="mailto:python-users@uni-koeln.de">python-users@uni-koeln.de</a><br>
Abonnement und Benutzereinstellungen: <a href="https://lists.uni-koeln.de/mailman/listinfo/python-users" rel="noreferrer" target="_blank">https://lists.uni-koeln.de/<wbr>mailman/listinfo/python-users</a><br>
Listenarchiv: <a href="http://pycologne.de/mlsearch.html" rel="noreferrer" target="_blank">http://pycologne.de/mlsearch.<wbr>html</a><br>
<br>
pyCologne Homepage: <a href="http://pycologne.de/" rel="noreferrer" target="_blank">http://pycologne.de/</a><br>
<br></blockquote></div><br></div>