models.py büyüyor, onu bölmenin en iyi yolu nedir?


91

Amirimin talimatları: "İçine herhangi bir mantık koymaktan kaçınmak istiyorum models.py. Bundan sonra, bunu sadece veritabanına erişmek için sınıflar olarak kullanalım ve tüm mantığı model sınıflarını kullanan harici sınıflarda saklayalım veya paketleyelim."

Bunun yanlış bir yol olduğunu düşünüyorum. Dosyayı küçük tutmak için mantığı modellerin dışında tutmanın kötü bir fikir olduğunu düşünüyorum. Mantık modelde en iyiyse, dosya boyutundan bağımsız olarak gerçekten gitmesi gereken yer orasıdır.

Öyleyse, eklentileri kullanmanın basit bir yolu var mı? PHP dilinde, süpervizöre models.pybaşka yerlerden model sınıflarını dahil ettiğimizi () önermek istiyorum . Kavramsal olarak, bu, modellerin istediğimiz tüm mantığa sahip olmasına izin verir, ancak dosya sayısını artırarak dosya boyutunu düşürür (bu, çakışmalar gibi daha az revizyon kontrol sorununa yol açar).

Öyleyse, model sınıflarını models.py dosyasından kaldırmanın basit bir yolu var, ancak yine de modeller tüm Django araçlarıyla çalışıyor mu? Veya, "büyük" bir models.py dosyasının genel sorununa tamamen farklı ama zarif bir çözüm var mı? Herhangi bir girdi takdir edilecektir.


7
İthalat beyanını biliyorsun, değil mi?
balpha

7
PS. Bunu saldırgan olarak kastetmiyorum, sadece nerede olduğunu bilmek istiyorum.
balpha

1
Evet, ancak django'nun yönetici araçlarının Modelleri içeri çekmek için yalnızca içe aktarma ifadelerini kullanarak çalışıp çalışmayacağını bilmiyordum. Sadece django'nun araçlarının onlarla iyi çalışmadığını öğrenmek için sade ole ithalatı kullanarak çok zaman harcamaktansa, burada sormayı tercih ederim. Sadece ithalat beyanı basit bir anlayışa muhtemelen olduğum o yüzden ..., Python ve django için yeni kulüpler itiraf
Eddified

Yanıtlar:


64

Django, tek bir büyük uygulama yerine birçok küçük uygulama oluşturmanıza izin vermek için tasarlanmıştır.

Her büyük uygulamanın içinde özgür olmaya çalışan birçok küçük uygulama vardır.

Senin Eğer models.pyhissettiğini büyük, çok fazla yapıyoruz. Dur. Rahatlayın. Ayrıştırın.

Daha küçük, potansiyel olarak yeniden kullanılabilir küçük uygulama bileşenlerini veya parçalarını bulun. Aslında onları yeniden kullanmak zorunda değilsiniz . Bunları potansiyel olarak yeniden kullanılabilir olarak düşünün.

Yükseltme yollarınızı düşünün ve bir gün değiştirmek isteyebileceğiniz uygulamaları ayrıştırın. Bunları gerçekten değiştirmek zorunda değilsiniz , ancak bunları gelecekte daha havalı bir şeyle değiştirilebilecek bağımsız bir programlama "modülü" olarak düşünebilirsiniz.

Yaklaşık bir düzine uygulamamız var, her model.pybiri yaklaşık 400 satırdan fazla kod içermiyor. Hepsi yaklaşık yarım düzineden daha az ayrık sınıf tanımına odaklanmış durumda. (Bunlar kesin sınırlar değil, kodumuzla ilgili gözlemlerdir.)

Erken ve sıklıkla ayrışıyoruz.


1
tam yerinde. önemsiz olmayan herhangi bir web uygulaması birkaç küçük 'uygulama' olacaktır. Katkıda bulunan ve diğer popüler uygulamalardan bir ipucu alın, kullanıcı kimlik doğrulaması bir uygulama, etiketleme başka bir uygulama, kullanıcı profilleri bir tane daha vb.
Javier

4
Bu "doğru" yol olsa da ve bilmek faydalı olsa da, tam olarak aradığım şey bu değildi. Ne tür bir cevap aradığımı bilmenin bir yolu yoksa özür dilerim. :)
Eddified

@Eddified: Bunu yapmazsanız, daha da kötüye gidecek. Şimdi bölmeye başlayın.
S.Lott

Yeterince komik, tam şu anda Jacob Kaplan Moss'u (OSCON'da) tam olarak bunu büyük ve son derece haklı ayrıntılarla açıklayan dinliyorum ;-).
Alex Martelli

13
Glenn Maynard'ın cevabı bu konuda çok daha iyi. Karmaşık bir web uygulamasını birçok uygulamaya bölmek kesinlikle iyi bir uygulamadır, ancak bir model.py dosyasını bir uygulama İÇİNDE yeniden düzenlemek de öyle. İki eylem ortogonal olabilir.
Erik

108

Model sınıflarının model üzerinde çalışacak yöntemleri içermesi doğaldır. Bir yöntemle birlikte bir Kitap modelim varsa, book.get_noun_count()ait olduğu yer orasıdır - get_noun_count(book)yöntem aslında başka bir pakete ait olmadığı sürece " " yazmak zorunda kalmak istemiyorum . (Örneğin, Amazon'un API'sine " get_amazon_product_id(book)" ile erişmek için bir paketim varsa olabilir .)

Django'nun dokümantasyonu modelleri tek bir dosyaya koymayı önerdiğinde ürktüm ve en başından itibaren onu uygun bir alt pakete nasıl ayıracağımı bulmak için birkaç dakika ayırdım.

site/models/__init__.py
site/models/book.py

__init__.py şöyle görünüyor:

from .book import Book

bu yüzden hala "site.models ithal Kitabı" yazabilirim.


Aşağıdakiler yalnızca Django 1.7'den önceki sürümler için gereklidir, bkz. Https://code.djangoproject.com/ticket/3591

Tek numara, Django'daki bir hata nedeniyle her modelin uygulamasını açıkça ayarlamanız gerektiğidir: uygulama adının model yolunda üçüncüden sonuncuya girdi olduğunu varsayar. "site.models.Book", doğru olan "site" sonucunu verir; "site.models.book.Book", uygulama adının "modeller" olduğunu düşünmesini sağlar. Bu, Django açısından oldukça çirkin bir hack; bir önek eşleşmesi için muhtemelen yüklü uygulamaların listesini aramalıdır.

class Book(models.Model):
    class Meta: app_label = "site"

Muhtemelen bunu genellemek için bir temel sınıf veya metasınıf kullanabilirsiniz, ancak henüz bununla uğraşmadım.


2
+1 Bunu başarıyla kullandım. S. Lott birden fazla uygulamada haklı olsa da iyi bir fikir olsa da, burada ve şimdi çözüm budur.
Alexander Ljungberg

35
Modelleriniz yakından ve içsel olarak ilişkili olduğunda, işleri bir grup uygulamaya bölmenin pek bir yararı görmüyorum.
Glenn Maynard

2
Bu beni ilgilendiriyor. Gönderilen django wiki bağlantısını okudum ve şunu buldum: "Bunun, mevcut ana dalda Meta sınıfı app_labels olmadan çalıştığı doğrulandı." Bu, ana şubeyle çalışıyorsanız, Meta: app_label öğelerini atabileceğimiz anlamına mı geliyor? Bu sorunu çözmek için biletle ilgili yorumdan sonra olduğu için kafa karıştırıcı.
Dan.StackOverflow

2
Sadece gövde ile test ettim (bugün erken saatlerde, r11286); app_name ayarlanmadıysa, model "sqlall appname" içinde görünmez ve muhtemelen syncdb tarafından oluşturulmaz (ama bunu kullanmıyorum, bu yüzden test edemem) Bu oldukça kafa karıştırıcı bir hata durumudur çünkü herhangi bir hatayı tetiklemez; sadece sessizce görünmüyor.
Glenn Maynard

2
Vay canına, yaklaşık 10 yıl sonra ve hala bu çözümü seviyorum. Kodunuzu daha küçük uygulamalara bölmekten çok daha iyi bir yaklaşım olduğu konusunda hemfikirim, bu da bence akıl yürütmesi zor bir kod tabanına yol açabilir.
Michael Hays

5

Olası birçok sorundan hangisine sahip olabileceğinizi tam olarak anlayamıyorum. İşte cevaplarla ilgili bazı olasılıklar:

  • aynı dosyada birden çok model

    Bunları ayrı dosyalara koyun. Bağımlılıklar varsa, ek modelleri çekmek için içe aktarmayı kullanın.

  • models.py'deki yabancı mantık / yardımcı program işlevleri

    Ekstra mantığı ayrı dosyalara koyun.

  • veritabanından bazı model örneklerini seçmek için statik yöntemler

    Ayrı bir dosyada yeni bir Yönetici oluşturun .

  • açıkça modelle ilgili yöntemler

    save, __unicode__ ve get_absolute_url örneklerdir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.