[python] models.py가 점점 커지고 있는데, 그것을 나누는 가장 좋은 방법은 무엇입니까?

내 상사의 지시 : “나는 로직을 models.py. 에 넣는 것을 피하고 싶다 . 이제부터는 데이터베이스 액세스를위한 클래스로만 사용하고 모델 클래스를 사용하는 외부 클래스에 모든 로직을 유지하거나 래핑합니다.”

나는 이것이 잘못된 길이라고 생각합니다. 파일을 작게 유지하기 위해 모델에서 논리를 제외하는 것은 나쁜 생각이라고 생각합니다. 논리가 모델에서 가장 좋은 경우 파일 크기에 관계없이 실제로 있어야합니다.

그렇다면 include를 사용하는 간단한 방법이 있습니까? PHP-speak에서 저는 models.py다른 곳의 모델 클래스를 include () 가지고 있다고 감독자에게 제안하고 싶습니다 . 개념적으로 이것은 모델이 우리가 원하는 모든 논리를 갖도록 허용하지만 파일 수를 늘려 파일 크기를 줄 이도록합니다 (충돌 등과 같은 수정 제어 문제를 줄임).

그렇다면 models.py 파일에서 모델 클래스를 제거하는 간단한 방법이 있지만 여전히 모든 Django 도구에서 모델이 작동합니까? 아니면 “대형”models.py 파일의 일반적인 문제에 대한 완전히 다르지만 우아한 해결책이 있습니까? 모든 입력을 주시면 감사하겠습니다.



답변

Django는 하나의 큰 응용 프로그램 대신 많은 작은 응용 프로그램을 빌드 할 수 있도록 설계되었습니다.

모든 대형 애플리케이션 내부에는 자유를 위해 고군분투하는 많은 작은 애플리케이션이 있습니다.

귀하의 경우 models.pyFeel로 큰, 당신은 너무 많은 일을하고 있습니다. 중지. 편하게 하다. 분해.

더 작고 재사용 가능한 소형 애플리케이션 구성 요소 또는 조각을 찾으십시오. 실제로 재사용 할 필요는 없습니다 . 잠재적으로 재사용 가능하다고 생각하십시오.

업그레이드 경로를 고려하고 언젠가 교체 할 수있는 애플리케이션을 분해하십시오. 당신은 필요가 없습니다 실제로 교체,하지만 당신은 미래에 뭔가 쿨러로 대체 될 수있는 위치를 프로그래밍의 독립 실행 형 “모듈”로 그들을 고려할 수 있습니다.

우리는 약 12 ​​개의 응용 프로그램을 가지고 있으며 각각 model.py은 약 400 줄의 코드를 넘지 않습니다. 그것들은 모두 6 개 미만의 개별 클래스 정의에 꽤 집중되어 있습니다. (이것은 엄격한 한계가 아니라 우리 코드에 대한 관찰입니다.)

우리는 일찍 그리고 자주 분해됩니다.


답변

모델 클래스가 모델에서 작동하는 메서드를 포함하는 것은 당연합니다. 메소드가있는 Book 모델이 있다면 book.get_noun_count()그것이 속한 곳입니다 get_noun_count(book). 메소드가 실제로 본질적으로 다른 패키지에 속하지 않는 한 ” ” 를 작성하고 싶지 않습니다 . (예 : ” get_amazon_product_id(book)“를 사용하여 Amazon의 API에 액세스하기위한 패키지가있는 경우 )

나는 Django의 문서가 모델을 단일 파일에 넣는 것을 제안했을 때 마음에 들었고 처음부터 적절한 하위 패키지로 분할하는 방법을 알아내는 데 몇 분이 걸렸습니다.

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

__init__.py 다음과 같이 보입니다.

from .book import Book

그래도 “from site.models import Book”을 쓸 수 있습니다.


다음은 Django 1.7 이전 버전에만 필요합니다.
https://code.djangoproject.com/ticket/3591 참조

유일한 트릭은 Django의 버그로 인해 각 모델의 애플리케이션을 명시 적으로 설정해야한다는 것입니다. 애플리케이션 이름이 모델 경로의 마지막에서 세 번째 항목이라고 가정합니다. “site.models.Book”은 올바른 “site”가됩니다. “site.models.book.Book”은 응용 프로그램 이름이 “models”라고 생각하게합니다. 이것은 Django의 부분에서 매우 불쾌한 해킹입니다. 아마도 설치된 응용 프로그램 목록에서 접두사 일치를 검색해야합니다.

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

이를 일반화하기 위해 기본 클래스 또는 메타 클래스를 사용할 수 있지만 아직 신경 쓰지 않았습니다.


답변

나는 당신이 가질 수있는 많은 가능한 문제들 중 어느 것을 확실히 알 수 없습니다. 답변이있는 몇 가지 가능성은 다음과 같습니다.

  • 동일한 파일에있는 여러 모델

    별도의 파일에 넣으십시오. 종속성이있는 경우 가져 오기를 사용하여 추가 모델을 가져옵니다.

  • models.py의 관련없는 논리 / 유틸리티 함수

    추가 로직을 별도의 파일에 넣으십시오.

  • 데이터베이스에서 일부 모델 인스턴스를 선택하기위한 정적 메소드

    별도의 파일에 새 관리자 를 만듭니다 .

  • 모델과 분명히 관련된 방법

    save, __unicode__ 및 get_absolute_url이 예입니다.


답변