Question

Je viens juste de finir de travailler sur les tutoriels Django pour la deuxième fois et je comprends les choses beaucoup plus clairement maintenant. Cependant, je ne sais toujours pas comment les applications d'un site Web interagissent les unes avec les autres.

Par exemple, disons que je suis en train d’écrire une application de blog (une activité plutôt populaire, apparemment). Les articles de blog et les commentaires vont généralement de pair, mais ils sont suffisamment distincts pour pouvoir être intégrés à des applications distinctes, comme le veut la philosophie générale du développement de Djano.

Considérez l'exemple suivant. En réalité, je n’écrirais pas moi-même l’application de commentaire, car il existe déjà un bon code pour cela sur le Web, mais c’est à des fins de démonstration / pratique:

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 / comments / 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()

Est-ce que ce que j'ai écrit ci-dessus est d'importer un modèle depuis une autre application et de le définir comme clé étrangère, comment les applications Django interagissent-elles? Ou existe-t-il une méthode différente / meilleure pour les applications qui composent un site pour interagir?

Mettre à jour
Selon la recommandation d'une réponse, je lis la documentation de contrib.contenttypes. Si je lis ceci correctement, je pourrais réécrire mon exemple d'application de commentaire comme ceci:

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)  

Cela serait-il correct?

Était-ce utile?

La solution

Jetez un coup d'œil aux contenttypes intégrés à django cadre :

django.contrib.contenttypes

Il vous permet de développer vos applications en tant qu’appareils autonomes. C’est ce que les développeurs de Django utilisaient pour autoriser la fonctionnalité intégrée de framework de commentaires pour attacher un commentaire à n’importe quel modèle de votre projet.

Par exemple, si vous voulez un objet de contenu que vous souhaitez &, attachez &, quot; à d'autres objets de contenu de types différents, comme permettre à chaque utilisateur de laisser un & "favori &"; Si vous êtes une étoile sur un blog, une image ou un profil utilisateur, vous pouvez créer un modèle Favorite avec un champ de relation générique comme suit:

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')

De cette manière, vous pouvez ajouter une étoile content_type de n'importe quel utilisateur à n'importe quel modèle de votre projet. Si vous souhaitez ajouter un accès à l'API via la classe de modèle du destinataire, vous pouvez ajouter un champ de relation générique inverse sur le modèle de destinataire (bien qu'il s'agisse de & "; coupler &"; les deux modèles que vous avez dit vouloir éviter), ou effectuer la recherche via le modèle object_id avec les <=> et <=> instances du destinataire, consultez le documents officiels pour un exemple.

Autres conseils

& "; Est-ce que ce que j'ai écrit ci-dessus est d'importer un modèle depuis une autre application et de le définir comme clé étrangère, comment les applications Django interagissent? &";

Oui. Ça marche pour moi.

Nous avons environ 10 applications qui empruntent entre elles.

Ceci conduit à une sorte de dépendance dans notre script de test unitaire.

Cela ressemble à ceci.

  • & "; propriété &" ;. Nous avons une application de propriété de données simple qui définit certains concepts de propriété fondamentaux sur lesquels reposent les autres applications. Il y a quelques tableaux simples ici.

  • & "chose &". [Pas le vrai nom]. Notre application contient des éléments de données appartenant à différents groupes d'utilisateurs. Il existe en fait plusieurs tables complexes du modèle pour cette application. Cela dépend de & "; La propriété &";.

  • & "tables &" ;. [Pas le vrai nom]. Certains de nos utilisateurs créent des modèles hors ligne assez complexes (probablement avec des feuilles de calcul) et téléchargent les résultats de cette modélisation dans & "Tableaux &"; Cela a un groupe de tables assez complexes. Cela dépend de & "; La propriété &";.

  • & "résultat &"; [Pas le vrai nom]. Nos résultats sont basés sur des choses qui ont des propriétaires. Les résultats sont basés sur des éléments et des tableaux et constituent des réponses aux demandes des clients. Ce n'est pas trop complexe, peut-être que deux ou trois tables principales. Cela dépend de & "; Les choses &"; et " table " ;. Non, ce n'est pas complètement autonome. Cependant, il est sujet à plus de changement que les autres choses dont il dépend. C'est pourquoi c'est séparé.

  • " traitement ". Nous planifions et surveillons les gros travaux par lots. Ceci est dans cette application. C'est vraiment générique et peut être utilisé de différentes façons. Il est complètement seul.

  • & "bienvenue &". Nous avons un & Quot; bienvenue & Quot; application qui présente un tas de pages essentiellement statiques. Cela n'a pas trop de tables. Mais c'est sur sa deuxième incarnation parce que la première était trop complexe. Il est complètement seul.

La seule relation entre les applications dépendantes est quelques noms de table. Tant que nous conservons ces tables (et leurs clés), nous pouvons réorganiser les autres applications comme bon nous semble.

Il n’ya rien de mal à rendre une application dépendante d’une autre. Après tout, les applications ne sont que des opérations sur un ensemble de modèles. vous devez juste toujours savoir quelle application dépend de quelle application (je suppose que vous pourriez appeler cela une carte de dépendance).

Vous pouvez réaliser un couplage lâche avec le framework contenttypes. Il permet à une application d'être réellement portable / connectable tout en restant intégrée à d'autres applications.

J'ai écrit une application de commentaires (oui, j'ai réinventé la roue), qui peut être intégrée à toute autre application, avec quelques lignes dans le modèle de la page où les commentaires doivent être publiés (à l'aide de balises personnalisées).

Disons que vous voulez un modèle " thread " être branché sur un autre modèle. L'idée est de créer une clé étrangère générique (voir la documentation de Django à ce sujet) et d'écrire une petite fonction qui prend n'importe quel objet et retourne un & "Thread &"; correspondant (ou en crée un si nécessaire) et écrivez une balise de modèle personnalisée qui utilise cette fonctionnalité, par exemple. {% get_thread for arbitrary_object as thread %} Toutes les publications sont liées à un fil de discussion, qui est lié à l'objet, qui peut être de n'importe quel type.

Vous pouvez penser au " fil " object comme une sorte de proxy, donc au lieu d’avoir un message, soyez lié à un certain " article " ou un " billet de blog " ;, il est simplement lié à un fil de discussion, ce qui est abstrait en un sens. Qu'est-ce que est un fil? C'est juste une collection de messages. Le thread s'autorise alors à être associé à n'importe quel objet, quel que soit son type. (bien qu’il fasse plus que cela, il pourrait contenir des informations supplémentaires telles que l’autorisation / le refus de publication, les commentaires de fermeture / ouverture sur la page, etc.)

MODIFIER

Voici comment créer une clé étrangère générique avec la structure des types de contenu:

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')

Vous pouvez le rendre plus & "transparent &"; en exploitant le " commun " interface que django suppose que tous les objets implémentent ..

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

Votre code semble correct. Je conserverais toutefois le message et le commentaire dans une application blog . Je ne dis pas que c'est la façon Django, mais ces modèles sont suffisamment proches pour être dans la même application.

Comment diviser le projet

Je séparerais une application si;

  • Je prévois de le concevoir de manière à ce qu'il puisse être réparé. (et essayez un couplage lâche)
  • (pour les grands projets) Il s’agit d’une grande partie du projet.

D'autre part; Il est difficile de lire et de gérer un IMHO avec beaucoup d'applications minuscules (comme une application avec un seul modèle et deux vues).

Comment les applications doivent-elles interagir

Cela dépend du type de projet et du type de l'application à nouveau. Par exemple, si une application dépend implicitement d'une autre (c'est-à-dire non générique), l'importation et l'utilisation de références provenant de l'autre application sont acceptables. Dans ce cas, la deuxième application peut être installée seule, mais la première nécessite la présence de la deuxième.

Si vous souhaitez rendre une application hautement réutilisable et générique, telle qu'une application de commentaire, vous devrez peut-être intégrer un mécanisme de configuration. Peut-être que de nouveaux paramètres ou une configuration d’URL supplémentaire, ou une directive / méthode spéciale sur vos modèles ... django.contrib.admin en est un bon exemple.

Les applications ne doivent pas interagir si cela n’est pas nécessaire. Concevoir des applications pour éviter les couplages inutiles est très utile. Il améliore la flexibilité de votre application et la rend plus facile à gérer (mais éventuellement avec un coût d'intégration plus élevé).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top