131 votes

Diviser models.py en plusieurs fichiers

J'essaie de diviser le models.py de mon application en plusieurs fichiers :

J'ai d'abord pensé qu'il fallait faire cela :

myproject/
    settings.py
    manage.py
    urls.py
    __init__.py
    app1/
        views.py
        __init__.py
        models/
            __init__.py
            model1.py
            model2.py
    app2/
        views.py
        __init__.py
        models/
            __init__.py
            model3.py
            model4.py

Cela ne fonctionne pas, puis j'ai trouvé este Mais dans cette solution, j'ai toujours un problème, lorsque je lance python manage.py sqlall app1 J'ai obtenu quelque chose comme :

BEGIN;
CREATE TABLE "product_product" (
    "id" serial NOT NULL PRIMARY KEY,
    "store_id" integer NOT NULL
)
;
-- The following references should be added but depend on non-existent tables:
-- ALTER TABLE "product_product" ADD CONSTRAINT "store_id_refs_id_3e117eef" FOREIGN KEY     ("store_id") REFERENCES "store_store" ("id") DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX "product_product_store_id" ON "product_product" ("store_id");
COMMIT;

Je ne suis pas très sûr de moi, mais je suis inquiet pour cette partie. The following references should be added but depend on non-existent tables:

Voici mon fichier model1.py :

from django.db import models

class Store(models.Model):
    class Meta:
        app_label = "store"

Voici mon fichier model3.py :

from django.db import models

from store.models import Store

class Product(models.Model):
    store = models.ForeignKey(Store)
    class Meta:
        app_label = "product"

Apparemment, cela fonctionne, mais j'ai reçu le commentaire suivant alter table et si j'essaie ceci, la même chose se produit :

class Product(models.Model):
    store = models.ForeignKey('store.Store')
    class Meta:
        app_label = "product"

Dois-je donc lancer manuellement le programme alter pour les références ? Cela risque-t-il de me poser des problèmes avec South ?

194voto

Vic Points 1210

Pour tous ceux qui utilisent Django 1.9, il est maintenant pris en charge par le framework sans avoir à définir les métadonnées de la classe.

https://docs.djangoproject.com/en/1.9/topics/db/models/#organizing-models-in-a-package

NOTE : Pour Django 2, c'est toujours la même chose

Les manage.py startapp crée une structure d'application qui inclut un fichier models.py. Si vous avez de nombreux modèles, il peut être utile de les organiser dans des fichiers séparés.

Pour ce faire, créez un paquet de modèles. Supprimez models.py et créez un fichier myapp/models/ avec un __init__.py et les fichiers pour stocker vos modèles. Vous devez importer les modèles dans le fichier __init__.py fichier.

Ainsi, dans votre cas, pour une structure comme

app1/
    views.py
    __init__.py
    models/
        __init__.py
        model1.py
        model2.py
app2/
    views.py
    __init__.py
    models/
        __init__.py
        model3.py
        model4.py

Il suffit de faire

#myproject/app1/models/__init__.py:
from .model1 import Model1
from .model2 import Model2

#myproject/app2/models/__init__.py:
from .model3 import Model3
from .model4 import Model4

Il est déconseillé d'importer toutes les classes :

Importer explicitement chaque modèle plutôt que d'utiliser la fonction from .models import * présente l'avantage de ne pas encombrer l'espace de noms, de rendre le code plus lisible et de préserver l'utilité des outils d'analyse du code.

40voto

Ted Points 1886

Je ferais ce qui suit :

myproject/
    ...
    app1/
        views.py
        __init__.py
        models.py
        submodels/
            __init__.py
            model1.py
            model2.py
    app2/
        views.py
        __init__.py
        models.py
        submodels/
            __init__.py
            model3.py
            model4.py

Dans ce cas

#myproject/app1/models.py:
    from submodels/model1.py import *
    from submodels/model2.py import *

#myproject/app2/models.py:
    from submodels/model3.py import *
    from submodels/model4.py import *

Mais, si vous n'avez pas de bonne raison, mettez model1 et model2 directement dans app1/models.py et model3 et model4 dans app2/models.py

--- deuxième partie ---

Il s'agit du fichier app1/submodels/model1.py :

from django.db import models
class Store(models.Model):
    class Meta:
        app_label = "store"

Corrigez donc votre fichier model3.py :

from django.db import models
from app1.models import Store

class Product(models.Model):
    store = models.ForeignKey(Store)
    class Meta:
        app_label = "product"

Modifié, au cas où cette question se poserait à nouveau pour quelqu'un : Consultez django-schedule pour un exemple de projet qui fait exactement cela. https://github.com/thauber/django-schedule/tree/master/schedule/models https://github.com/thauber/django-schedule/

11voto

Adam Luchjenbroers Points 2404

J'ai trouvé un tutoriel qui répond exactement à votre question, vous pouvez le consulter ici :

https://web.archive.org/web/20190331105757/http://paltman.com/breaking-apart-models-in-django/

Un point clé qui est probablement pertinent - vous pouvez utiliser le champ db_table de la classe Meta pour renvoyer les classes relocalisées à leur propre table.

Je peux confirmer que cette approche fonctionne dans Django 1.3

9voto

KevinM Points 593

Le lien pertinent pour Django 3 est le suivant :

https://docs.djangoproject.com/en/3.2/topics/db/models/#organizing-models-in-a-package

Les liens vers les versions précédentes de la documentation ne fonctionnent plus. L'exemple est très succinct :

Pour ce faire, créez un paquet de modèles. Supprimez models.py et créez un répertoire myapp/models/ avec un fichier init .py et les fichiers pour stocker vos modèles. Vous devez importer les modèles dans le fichier init .py.

Par exemple, si vous avez organic.py et synthetic.py dans le répertoire models :

from .organic import Person
from .synthetic import Robot

1voto

Parth Jani Points 25

Les étapes les plus faciles :

  1. Créez un dossier modèle dans votre application (le nom du dossier doit être modèle )
  2. Supprimer le fichier model.py du répertoire app (Sauvegardez le fichier pendant que vous le supprimez)
  3. Et après avoir créé init Fichier .py dans le dossier du modèle
  4. Et après init fichier .py dans write simple one line
  5. Ensuite, créez un fichier de modèle dans votre dossier de modèle et le nom du fichier de modèle doit être le même que celui de la classe, Si le nom de la classe est "Employee", le nom du fichier modèle doit être "employee.py".
  6. Ensuite, dans le fichier modèle, définissez votre table de base de données en écrivant comme suit model.py fichier
  7. Sauvegarde

Mon code : from django_adminlte.models.employee import Employee

Pour votre : de Nom de l'application .modèles. nom_du_fichier_modèle l'importation Nom_de_classe_qui_définit_dans_le_fichier_modèle


__init__.py

from django_adminlte.models.employee import Employee

model/employee.py (employee is separate model file)

from django.db import models

class Employee(models.Model):
eid = models.CharField(max_length=20)
ename = models.CharField(max_length=20)
eemail = models.EmailField()
econtact = models.CharField(max_length=15)

class Meta:
    db_table = "employee"
    # app_label = 'django_adminlte'

def __str__(self):
    return self.ename

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X