webentwicklung-frage-antwort-db.com.de

Teilen Sie models.py in mehrere Dateien auf

Ich versuche, den models.py meiner App in mehrere Dateien aufzuteilen:

Meine erste Vermutung lautete:

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

Das funktioniert nicht, dann habe ich this gefunden, aber in dieser Lösung habe ich immer noch ein Problem, wenn ich python manage.py sqlall app1 starte, habe ich etwas wie

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;

Ich bin mir nicht ganz sicher, aber ich mache mir Sorgen um den Teil The following references should be added but depend on non-existent tables:

Dies ist meine model1.py-Datei:

from Django.db import models

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

Dies ist meine model3.py-Datei:

from Django.db import models

from store.models import Store

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

Und anscheinend funktioniert, aber ich bekam den Kommentar in alter table und wenn ich das versuche, passiert dasselbe:

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

Soll ich die Änderung für Referenzen manuell ausführen? das kann mir probleme mit süden bringen?

64
diegueus9

Ich kann mir gar nicht vorstellen, warum Sie das tun wollen. Aber ich nehme an, du hast einen guten Grund. Wenn ich dies aus irgendeinem Grund tun müsste, würde ich Folgendes tun:

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

Dann

#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 *

Wenn Sie jedoch keinen triftigen Grund haben, setzen Sie model1 und model2 direkt in app1/models.py und model3 und model4 in app2/models.py

---zweiter Teil---

Dies ist die app1/submodels/model1.py Datei:

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

So korrigieren Sie Ihre model3.py-Datei:

from Django.db import models
from app1.models import Store

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

Bearbeitet, falls dies für jemanden erneut angezeigt wird: Schauen Sie sich Django-Zeitplan für ein Beispiel eines Projekts an, das genau dies tut . https://github.com/thauber/Django-schedule/ Baum/Master/Zeitplan/Modellehttps://github.com/thauber/Django-schedule/

25
Ted

Für alle, die Django 1.9 verwenden, wird es jetzt vom Framework unterstützt, ohne die Metadaten der Klasse zu definieren.

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

HINWEIS: Für Django 2 ist es ist immer noch dasselbe

Der Befehl manage.py startapp erstellt eine Anwendungsstruktur, die eine models.py-Datei enthält. Wenn Sie über viele Modelle verfügen, kann es hilfreich sein, sie in separaten Dateien zu organisieren.

Erstellen Sie dazu ein Modellpaket. Entfernen Sie models.py und erstellen Sie ein myapp/models/-Verzeichnis mit einer __init__.py-Datei und den Dateien, in denen Ihre Modelle gespeichert werden. Sie müssen die Modelle in die __init__.py-Datei importieren.

Also in Ihrem Fall für eine Struktur wie

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

Sie müssen nur tun

#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

Ein Hinweis gegen das Importieren aller Klassen:

Das explizite Importieren jedes Modells anstelle der Verwendung von from .models import * hat den Vorteil, dass der Namespace nicht überladen wird, der Code lesbarer wird und die Werkzeuge zur Analyse von Code nützlich bleiben.

97
Vic

Ich habe tatsächlich ein Tutorial für genau das gefunden, worüber Sie fragen, Sie können es hier ansehen:

http://paltman.com/breaking-apart-models-in-Django/

Ein wichtiger Punkt, der wahrscheinlich relevant ist - Sie möchten möglicherweise das Feld db_table der Meta-Klasse verwenden, um die verschobenen Klassen auf ihre eigene Tabelle zu verweisen.

Ich kann bestätigen, dass dieser Ansatz in Django 1.3 funktioniert

11

Einfachste Schritte:

  1. Erstellen Sie einen Modellordner in Ihrer App (Der Ordnername sollte Modell sein)
  2. Löschen Sie die Datei model.py aus dem App-Verzeichnis (Sichern Sie die Datei, während Sie sie löschen)
  3. Und nach dem Erstellen von init. Py-Datei im Modellordner
  4. Und nach init. Py-Datei schreiben Sie einfach eine Zeile 
  5. Und nach dem Erstellen der Modelldatei in Ihrem Modellordner sollte der Modelldateiname dem Klassennamen entsprechen. Wenn der Klassenname 'Employee' lautet, sollte der Modelldateiname 'Employee.py' sein.
  6. Und danach in der Modelldatei definieren Sie Ihre Datenbanktabelle genauso wie in model.py -Datei
  7. Speichern Sie es

Mein Code: von Django_adminlte.models.employee import Employee

Für Ihre: aus app_name. Models .Modelldateiname_only import Klassenname_des_Daten_in_modells_Datei


__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
0
Parth Jani