स्प्लिट मॉडेम को कई फाइलों में विभाजित करें


89

मैं models.pyअपने ऐप को कई फाइलों में विभाजित करने की कोशिश कर रहा हूं :

मेरा पहला अनुमान यह था:

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

यह काम नहीं करता है, तो मुझे यह मिला , लेकिन इस समाधान में मुझे अभी भी एक समस्या है, जब मैं चलाता python manage.py sqlall app1हूं तो मुझे कुछ ऐसा मिला है:

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;

मैं इस बारे में बहुत निश्चित नहीं हूं, लेकिन मैं इस भाग को लेकर चिंतित हूं The following references should be added but depend on non-existent tables:

यह मेरी Model1.py फ़ाइल है:

from django.db import models

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

यह मेरी मॉडल 3 डी फ़ाइल है:

from django.db import models

from store.models import Store

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

और जाहिरा तौर पर काम करता है, लेकिन मुझे टिप्पणी मिली alter tableऔर अगर मैं यह कोशिश करता हूं, तो यही होता है:

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

तो, क्या मुझे मैन्युअल रूप से संदर्भों के लिए परिवर्तन चलाना चाहिए? यह मुझे दक्षिण के साथ समस्याएं ला सकता है?


यदि आप कोशिश करते हैं तो मॉडल 3 में क्या होता है from app1.models.model1 import Store?
जेम्स खूर्नी

इसके अलावा, आप की जाँच करने के लिए चाहते हो सकता है stackoverflow.com/questions/5534206/...
जेम्स Khoury

जवाबों:


32

मैं निम्नलिखित कार्य करूंगा:

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

फिर

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

लेकिन, यदि आपके पास कोई अच्छा कारण नहीं है, तो model1 और model2 को सीधे app1 / model.py और model3 और model4 को app2 / model.py में रखें।

---दूसरा भाग---

यह app1 / submodels / model1.py फ़ाइल है:

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

इस प्रकार अपनी 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"

संपादित, यदि यह किसी के लिए फिर से आता है: एक परियोजना के उदाहरण के लिए django- शेड्यूल देखें जो यह करता है। https://github.com/thauber/django-schedule/tree/master/schedule/models https://github.com/thauber/django-schedule/


1
इस उत्तर के संबंध में मुझे एक और समस्या आई, जब model2.py कुछ बना देगा जैसे from product.models import Product: ImportError: कोई भी मॉडल जिसका नाम मॉडल नहीं है
diegueus9

68
आप इसे प्रति फ़ाइल एक कक्षा बनाए रखने के लिए इस तरह से करेंगे।
18

50
"क्यों" एक विशाल models.pyफ़ाइल के आकार को कम करने की इच्छा होगी । मैंने हाल ही में ऐसा तब किया था जब मेरा कोड की 15k से अधिक लाइनों तक विकास हुआ था। महान लेखन हालांकि। प्रक्रिया काफी सरल है। मुख्य कैविएट आपको एक स्पष्ट app_label को परिभाषित करने के लिए याद रखना होगा, क्योंकि Django डिफ़ॉल्ट रूप से तत्काल मॉड्यूल से इसे निकालता है।
सेरिन

1
2016 में यह एक कोशिश दे रहा है। क्या इस पोस्ट के दूसरे भाग की अभी भी आवश्यकता है? मैंने केवल फ़ाइलों को अलग करने के लिए कक्षाओं को स्थानांतरित किया, मेरा लिखा__init__.py और सब कुछ ठीक काम कर रहा है। मुझे अपनी मॉडल फ़ाइलों को सही करने की आवश्यकता नहीं थी। मैं खोल और django व्यवस्थापक से ऑब्जेक्ट लाने और बनाने में सक्षम हूं। मैं एक सप्ताह के लिए django की कोशिश कर रहा हूं, तो मैं सोच रहा हूं कि क्या नवीनतम संस्करण अब ऐसा करने की अनुमति देता है?
विक

3
@Vic: मेटा क्लास में app_label अब Django के नए संस्करणों के साथ आवश्यक नहीं है। देखें कोड.djangoproject.com/wiki/CookBookSplitModelsToFiles
jrial

147

Django 1.9 पर किसी के लिए, अब यह वर्ग मेटा डेटा को परिभाषित किए बिना फ्रेमवर्क द्वारा समर्थित है।

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

नोट: Django 2 के लिए, यह अभी भी एक ही है

manage.py startappआदेश एक आवेदन संरचना है कि एक models.py फ़ाइल शामिल पैदा करता है। यदि आपके पास कई मॉडल हैं, तो उन्हें अलग-अलग फ़ाइलों में व्यवस्थित करना उपयोगी हो सकता है।

ऐसा करने के लिए, एक मॉडल पैकेज बनाएं। अपने मॉडल को स्टोर करने के लिए myapp/models/एक __init__.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

आपको केवल करने की आवश्यकता है

#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

सभी वर्गों के आयात के खिलाफ एक नोट:

स्पष्ट रूप से प्रत्येक मॉडल का उपयोग करने के बजाय from .models import *नाम स्थान को अव्यवस्थित नहीं करने, कोड को अधिक पठनीय बनाने और कोड विश्लेषण टूल को उपयोगी रखने के फायदे हैं।


5
यदि कोई व्यक्ति सोच रहा है कि यह अभी भी Django 2.0 docs.djangoproject.com/en/2.0/topics/db/models/… के
NaturalBornCamper

6
नोट: यह आमतौर पर ठीक से काम नहीं करता है जब आपने शुरू किया है models.pyऔर बाद में माइग्रेट करना चाहते हैं। उस स्थिति में, आपको अपने माइग्रेशन और अपने डेटाबेस को हटाना होगा: / या मैन्युअल रूप से सभी माइग्रेशन फ़ाइलों में सभी त्रुटियों को हल करने के लिए
tuergeist

सबसे अच्छा जवाब अभी भी। इस बात की पुष्टि अभी भी 2.1+
Roys

मैं Django 3.0 में @tuergeist द्वारा बताई गई समस्या को नहीं देखता। एक आकर्षण की तरह काम करने लगता है
कैरम

11

मैं वास्तव में एक ट्यूटोरियल भर में आया हूँ, जिसके बारे में आप पूछ रहे हैं, आप इसे यहाँ देख सकते हैं:

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

एक प्रमुख बिंदु जो संभवतः प्रासंगिक है - आप मेटा क्लास पर db_table फ़ील्ड का उपयोग करना चाहते हैं ताकि स्थानांतरित वर्ग को अपनी टेबल पर वापस इंगित कर सकें।

मैं पुष्टि कर सकता हूं कि यह दृष्टिकोण Django 1.3 में काम कर रहा है


वह लिंक 404
ब्रायन ओकले

1

सबसे आसान चरण:

  1. अपने एप्लिकेशन में मॉडल फ़ोल्डर बनाएं (फ़ोल्डर का नाम मॉडल होना चाहिए )
  2. मॉडल निर्देशिका फ़ाइल को ऐप निर्देशिका से हटाएं (फ़ाइल को हटाते समय बैकअप लें)
  3. और मॉडल फोल्डर में init .py फाइल बनाने के बाद
  4. और init के बाद .py फाइल को सरल एक पंक्ति में लिखें
  5. और अपने मॉडल फोल्डर में मॉडल फाइल बनाने के बाद और मॉडल फाइल का नाम कक्षा के नाम की तरह ही होना चाहिए, अगर क्लास का नाम 'कर्मचारी' है तो मॉडल फाइल का नाम 'एंप्लॉयमेंट' जैसा होना चाहिए।
  6. और मॉडल फ़ाइल के बाद अपने डेटाबेस तालिका को उसी तरह परिभाषित करें जैसे कि मॉडल थिंकहोम में लिखते हैं फ़ाइल
  7. बचाओ

मेरा कोड: django_adminlte.models.employee आयात कर्मचारी से

आपके लिए: app_name .models से model_file_name_only Class_Name_which_define_in_model_file आयात करें


__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

2
यह वही है जो वह ठीक करने की कोशिश कर रहा है। यह समाधान RuntimeError ModelX doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.django 2.x में पैदा करेगा ।
राडेक

0

मैंने एक स्क्रिप्ट लिखी जो उपयोगी हो सकती है।

github.com/victorqribeiro/splitDjangoModels

यह उचित नामकरण और आयात के साथ मॉडल को अलग-अलग फ़ाइलों में विभाजित करता है; यह एक init फ़ाइल भी बनाता है ताकि आप एक ही बार में अपने सभी मॉडल आयात कर सकें।

मुझे बताएं क्या इससे मदद मिलती है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.