Django 개발자가 저지르는 상위 10가지 실수
게시 됨: 2022-03-11이 튜토리얼에서는 Django 개발자가 자주 범하는 몇 가지 일반적인 실수와 이를 방지하는 방법을 살펴보겠습니다. 이 튜토리얼은 관리할 수 없을 정도로 큰 설정을 유지하거나 정적 자산에서 이름 충돌과 같은 실수가 Django를 처음 사용하는 신규 개발자에게만 국한되지 않기 때문에 숙련된 Django 개발자라도 유용합니다.
Django는 일반적인 개발 문제를 유용하게 해결하고 유연하고 잘 구조화된 애플리케이션을 빌드할 수 있는 무료 오픈 소스 Python 웹 프레임워크입니다. Django에는 기본적으로 많은 현대적인 기능이 있습니다. 개인적으로 Admin, Object Relational Mapping tool(ORM), Routing, Templating 기능 때문에 Django는 응용 프로그램이 많은 작업을 필요로 하기 때문에 첫 번째 선택이 되었습니다. 이러한 기본 반복 작업에 가능한 한 적은 시간. Django를 사용하면 유연성을 손상시키지 않고 이 모든 작업을 수행할 수 있습니다.
Django의 킬러 기능은 모델의 스키마와 관리자 패널 모델에서 자동으로(자동으로?) 빌드되는 강력한 구성 가능한 관리자 인터페이스로, 마치 마법사가 된 것 같은 느낌을 줍니다. 관리자 인터페이스를 통해 사용자는 ACL(액세스 제어 목록), 행 수준 권한 및 작업, 필터, 주문, 위젯, 양식, 추가 URL 도우미 및 상상할 수 있는 모든 것을 포함하여 많은 것을 구성할 수 있습니다. 모든 애플리케이션에는 관리자 패널이 필요하다고 생각합니다. 아직 그렇지 않다면 기본 애플리케이션에 관리자 패널이 필요할 때까지 시간 문제일 뿐입니다. Django admin을 사용하면 빠르고 유연하게 만들 수 있습니다.
Django에는 기본적으로 모든 주요 데이터베이스와 함께 작동하는 강력한 ORM이 있습니다. 게으르기 때문에 다른 ORM과 달리 필요할 때만 데이터베이스에 도달합니다. Python 소스 코드에서 사용할 수 있는 모든 주요 SQL 명령(및 기능)을 지원하며 Python의 기능으로 인해 매우 편안합니다.
Django의 템플릿 엔진은 동시에 매우 유연하고 강력합니다. 많은 표준 필터 및 태그를 사용하고 프로젝트에 대한 새 사용자 정의 필터 및 태그를 생성할 수 있습니다. Django는 Django 템플릿뿐만 아니라 다른 템플릿 엔진을 지원하며 템플릿 처리를 위한 표준 바로 가기 기능을 통해 다른 템플릿 엔진과 쉽게 통합할 수 있는 API를 제공합니다.
Django에는 들어오는 요청을 구문 분석하고 라우터 스키마에서 새 URL을 빌드할 수 있는 URL 라우터와 같은 다른 많은 큰 기능이 있습니다. 전반적으로 Django 프레임워크는 즐거운 경험이며 도움이 필요할 때마다 설명서를 읽어보세요.
실수 1: 프로젝트 종속성을 위한 글로벌 시스템 Python 환경 사용
프로젝트 종속성에 Python의 전역 환경을 사용하지 마십시오. 종속성 충돌이 발생할 수 있습니다. Python은 동시에 여러 패키지 버전을 사용할 수 없습니다. 이는 다른 프로젝트에 동일한 패키지의 서로 다른 호환되지 않는 버전이 필요한 경우 문제가 될 수 있습니다.
이 실수는 일반적으로 Python의 환경 격리 기능에 대해 모르는 새로운 Python 및 Django 개발자가 범합니다.
환경을 격리하는 방법에는 여러 가지가 있지만 가장 일반적인 방법은 다음과 같습니다.
- virtualenv: Python 환경 폴더를 생성하고 환경을 [비]활성화하고 환경에 설치된 Python 패키지를 관리하기 위한 스크립트가 있는 Python 패키지입니다. 이것은 작업을 수행하는 가장 간단한 방법이기 때문에 내가 가장 좋아하는 방법입니다. 일반적으로 프로젝트 폴더에 가까운 환경을 만듭니다.
- virtualenvwrapper: 전역적으로 설치되고 생성/삭제/활성화/등을 위한 도구 세트를 제공하는 Python 패키지. 가상 환경. 모든 가상 환경은 하나의 폴더에 저장됩니다(환경 변수 WORKON_HOME을 통해 재정의할 수 있음).
virtualenvwrapper대신virtualenv를 사용하면 어떤 이점도 없습니다. - 가상 머신(VM): 애플리케이션 전용 전체 가상 머신보다 더 큰 격리는 없습니다. VirtualBox(무료), VMware, Parallels 및 Proxmox(내가 개인적으로 가장 좋아하는 도구이며 무료 버전이 있음)를 포함하여 선택할 수 있는 도구가 많이 있습니다. Vagrant와 같은 VM 자동화 도구와 결합하면 매우 강력한 솔루션이 될 수 있습니다.
- 컨테이너: 지난 몇 년 동안 저는 거의 모든 프로젝트, 특히 처음부터 새로 시작하는 모든 프로젝트에서 Docker를 사용해 왔습니다. Docker는 많은 기능을 제공하고 컨테이너 자동화를 위한 많은 타사 도구를 제공하는 놀라운 도구입니다. 컨테이너를 매우 빠르게 재구축하는 레이어 캐싱 기능이 있습니다. 컨테이너에서는 모든 컨테이너에 자체 파일 시스템이 있고 프로젝트가 상위 수준에서 격리되기 때문에 전역 시스템 Python 환경을 사용합니다. Docker를 사용하면 특히 Docker 경험이 있는 경우 새 팀 구성원이 프로젝트 작업을 더 빨리 시작할 수 있습니다.
저에게 묻는다면 프로젝트 종속성 격리 및 관리를 위해 virtualenv Python 패키지와 Docker 컨테이너를 선호합니다.
실수 2: requirements.txt 파일에 프로젝트 종속성을 고정하지 않음
모든 새로운 Python 프로젝트는 requirements.txt 파일과 새로운 격리된 환경으로 시작해야 합니다. 일반적으로 pip/easy_install 을 통해 모든 패키지를 설치하지만 requirements.txt 파일에도 추가하는 것을 잊지 마십시오. 이렇게 하면 프로젝트를 서버에 배포하거나 팀 구성원이 자신의 컴퓨터에서 프로젝트를 부트스트랩하는 것이 더 쉬워집니다(더 적절할 수 있음).
또한 requirements.txt 파일에 특정 버전의 종속성을 고정 하는 것만큼이나 중요합니다. 일반적으로 패키지의 다른 버전은 다른 모듈, 기능 및 기능 매개변수를 제공합니다. 종속성의 사소한 버전 변경으로도 패키지가 손상될 수 있습니다. 버전 관리 없이 빌드 시스템이 항상 사용 가능한 최신 버전의 패키지를 설치하기 때문에 프로젝트가 실행 중이고 정기적으로 배포를 예약한 경우 이는 매우 심각한 문제입니다.
항상 생산을 위해 패키지를 고정하십시오! 개인적으로, 나는 이것을 하는 데 도움이 되는 pip-tools라는 아주 좋은 도구를 사용합니다. 종속성을 관리하는 데 도움이 되는 일련의 명령줄 도구를 제공합니다. 종속성뿐만 아니라 종속성의 종속성을 포함하는 전체 종속성 트리를 고정하는 requirements.txt 를 자동으로 생성합니다.
때로는 종속성 목록에서 일부 패키지(예: Django/Flask/모든 프레임워크 또는 유틸리티만)만 업데이트하려는 경우가 있습니다. "pip freeze"를 사용한 경우 어떤 종속성이 어떤 패키지에 대한 것인지 모르기 때문에 종속성을 업그레이드할 수 없습니다. 그러나 pip-tools를 사용하면 고정한 종속성에 따라 패키지를 자동으로 고정하므로 업데이트해야 하는 패키지가 자동으로 해결됩니다. 보너스로, requirements.txt 파일에서 주석으로 패키지를 표시하는 방식 때문에 어떤 패키지가 어떤 종속성에서 왔는지 정확히 알 수 있습니다.
더 주의하려면 종속성 소스 파일도 백업하는 것이 좋습니다! 파일 시스템, Git 관리 폴더, S3 폴더, FTP, SFTP 등 어디에서나 사본을 보관하되 손에 들고 있습니다. 목록에 없는 비교적 작은 패키지가 npm에서 많은 수의 패키지를 손상시킨 경우가 있었습니다. Pip는 필요한 모든 종속성을 소스 파일로 다운로드하기 위한 도구를 유용하게 제공합니다. pip help download 를 실행하여 자세한 내용을 읽어보세요.
실수 3: 클래스 기반 보기 대신 구식 Python 함수 사용
때로는 특히 테스트 또는 유틸리티 보기를 위해 애플리케이션의 views.py 파일에서 작은 Python 함수를 사용하는 것이 좋지만 일반적으로 애플리케이션에서 CBV(클래스 기반 보기)를 사용해야 합니다.
CBV는 전문가가 구축하고 모든 일반적인 동작을 다루는 일반적인 웹 개발 작업을 구현하는 추상 클래스를 제공하는 일반적인 보기입니다. 그들은 놀라운 구조의 API를 가지고 있으며 CBV를 사용할 때 객체 지향 프로그래밍의 모든 이점을 사용할 수 있습니다. 소스 코드를 더 명확하고 읽기 쉽게 만듭니다. 목록, CRUD 작업, 양식 처리 등에 Django 표준 보기 함수를 사용하는 수고를 잊어버리십시오. 보기에 적합한 CBV를 확장하고 클래스 속성 또는 함수를 재정의하기만 하면 됩니다(일반적으로 함수는 속성을 반환하고 거기에 논리를 추가할 수 있습니다. 보기 동작을 구성하는 CBV 대신 보기 기능을 사용하는 경우 소스 코드에서 스파게티를 만듭니다.
예를 들어, 보기 컨텍스트 작성, 행 수준에서 권한 부여 확인, 애플리케이션 구조에서 템플릿 경로 자동 작성, 스마트 캐싱 통합 등에 대한 기본 CBV 동작을 재정의하는 다양한 믹스인을 프로젝트에 가질 수 있습니다.
애플리케이션 이름과 보기 클래스 이름을 기반으로 보기의 템플릿 이름을 표준화하는 Django 템플릿 이름이라는 패키지를 만들었습니다. 나는 매일 그것을 사용하고 이름을 발명하는 데 많은 시간을 절약할 수 있습니다. 믹스인을 CBV class Detail(TemplateNames, DetailView): 작동하기 시작합니다! 물론 내 기능을 재정의하고 모바일 반응형 템플릿, 사용자 에이전트를 위한 다른 템플릿 또는 원하는 모든 것을 추가할 수 있습니다.
실수 4: 뚱뚱한 보기와 마른 모델 작성하기
모델 대신 보기에 애플리케이션 논리를 작성한다는 것은 모델에 속한 코드를 보기에 작성하여 보기를 "뚱뚱"하고 모델을 "날씬하게" 만들었다는 것을 의미합니다.
당신은 뚱뚱한 모델, 마른 견해를 작성해야합니다.
모델에서 논리를 작은 방법으로 나눕니다. 이를 통해 수많은 코드를 복사하여 붙여넣는 대신 몇 줄의 코드로 여러 소스(관리자 인터페이스 UI, 프런트 엔드 UI, API 끝점, 여러 보기)에서 여러 번 사용할 수 있습니다. 따라서 다음에 사용자에게 이메일을 보낼 때 컨트롤러에서 이 로직을 작성하는 대신 이메일 기능으로 모델을 확장하십시오.
또한 이 작업이 수행되는 모든 컨트롤러에서 반복적으로가 아니라 한 곳에서 이메일 논리를 테스트할 수 있기 때문에 코드를 더 쉽게 단위 테스트할 수 있습니다.
Django 모범 사례 프로젝트에서 문제에 대해 자세히 읽을 수 있습니다. 해결책은 간단합니다. 뚱뚱한 모델과 마른 보기를 작성하면 다음 프로젝트에서 하도록 하겠습니다(또는 현재 프로젝트를 리팩터링).
실수 5: 관리할 수 없는 거대한 설정 파일
새로운 Django 프로젝트 설정 파일에도 많은 설정이 있습니다. 실제 프로젝트에서 설정 파일은 700개 이상의 구성 라인으로 증가하고 특히 개발, 프로덕션 및 스테이징 환경에 모두 사용자 지정 구성이 필요한 경우 유지 관리가 어려워집니다.
구성 파일을 수동으로 분할하고 사용자 정의 로더를 생성할 수 있지만, 제가 공동 저작한 훌륭하고 잘 테스트된 Python 패키지인 Django Split Settings를 소개하고 싶습니다.
패키지는 경로에 대한 와일드카드를 지원하고 동일한 컨텍스트에서 구성 파일을 가져오는 두 가지 기능( optional 및 include )을 제공하므로 이전에 로드된 파일에 선언된 구성 항목을 사용하여 구성을 간단하게 빌드할 수 있습니다. Django 성능에 영향을 미치지 않으며 모든 프로젝트에서 사용할 수 있습니다.
최소 구성 예를 확인하십시오.
from split_settings.tools import optional, include include( 'components/base.py', 'components/database.py', 'components/*.py', # the project different envs settings optional('envs/devel/*.py'), optional('envs/production/*.py'), optional('envs/staging/*.py'), # for any local settings optional('local_settings.py'), )실수 6: 올인원 애플리케이션, 잘못된 애플리케이션 구조 및 잘못된 리소스 배치
모든 Django 프로젝트는 여러 애플리케이션으로 구성됩니다. Django 표기법에서 애플리케이션은 최소한 __init__.py 및 models.py 파일을 포함하는 Python 패키지입니다. 최신 Django 버전에서는 models.py 가 더 이상 필요하지 않습니다. __init__.py 이면 충분합니다.

Django 애플리케이션에는 Python 모듈, Django 관련 모듈(보기, URL, 모델, 관리자, 양식, 템플릿 태그 등), 정적 파일, 템플릿, 데이터베이스 마이그레이션, 관리 명령, 단위 테스트 등이 포함될 수 있습니다. 간단한 논리를 사용하여 모놀리식 응용 프로그램을 작고 재사용 가능한 응용 프로그램으로 나누어야 합니다. 하나 또는 두 개의 짧은 문장으로 앱의 전체 목적을 설명할 수 있어야 합니다. 예: "사용자가 이메일로 계정을 등록하고 활성화할 수 있습니다."
프로젝트 폴더 project 를 호출하고 응용 프로그램을 project/apps/ 에 배치하는 것이 좋습니다. 그런 다음 모든 애플리케이션 종속성을 자체 하위 폴더에 배치합니다.
예:
- 정적 파일:
project/apps/appname/static/appname/ - 템플릿 태그:
project/apps/appname/templatetags/appname.py - 템플릿 파일:
project/apps/appname/templates/appname/
모든 정적 폴더가 하나의 폴더로 병합되고 두 개 이상의 응용 프로그램에 js/core.js 파일이 있는 경우 settings.INSTALLED_APPLICATIONS 의 마지막 응용 프로그램이 이전 응용 프로그램을 재정의하므로 항상 하위 폴더에서 응용 프로그램 이름의 접두사를 지정합니다. 한 번 내 현재 프로젝트에 이 버그가 있었고 팀이 사용자 지정 SPA 관리 패널을 구현하고 파일 이름을 같은 방식으로 지정했기 때문에 다른 개발자가 static/admin/js/core.js 를 재정의했다는 것을 깨달을 때까지 약 6시간의 디버깅 시간을 잃었습니다.
다음은 리소스와 Python 모듈이 많은 포털 애플리케이션의 구조 예입니다.
root@c5b96c395cfb:/test# tree project/apps/portal/ project/apps/portal/ ├── __init__.py ├── admin.py ├── apps.py ├── management │ ├── __init__.py │ └── commands │ ├── __init__.py │ └── update_portal_feeds.py ├── migrations │ └── __init__.py ├── models.py ├── static │ └── portal │ ├── css │ ├── img │ └── js ├── templates │ └── portal │ └── index.html ├── templatetags │ ├── __init__.py │ └── portal.py ├── tests.py ├── urls.py └── views.py 11 directories, 14 files이러한 구조를 사용하면 언제든지 애플리케이션을 다른 Python 패키지로 내보내고 다시 사용할 수 있습니다. PyPi에 오픈 소스 패키지로 게시하거나 다른 폴더로 이동할 수도 있습니다.
다음과 같은 프로젝트 구조로 끝납니다.
root@c5b96c395cfb:/test# tree -L 3 . ├── deploy │ ├── chef │ └── docker │ ├── devel │ └── production ├── docs ├── logs ├── manage.py ├── media ├── project │ ├── __init__.py │ ├── apps │ │ ├── auth │ │ ├── blog │ │ ├── faq │ │ ├── pages │ │ ├── portal │ │ └── users │ ├── conf │ ├── settings.py │ ├── static │ ├── templates │ ├── urls.py │ └── wsgi.py └── static └── admin ├── css ├── fonts ├── img └── js 25 directories, 5 files물론 실제 프로젝트에서는 더 복잡하겠지만 이 구조는 일을 더 간단하고 깔끔하게 만듭니다.
실수 번호 7: STATICFILES_DIRS 및 STATIC_ROOT 초보자 Django 개발자를 혼란스럽게 합니다.
정적 파일은 앱 사용을 통해 변경되지 않는 자산입니다(예: JavaScript, CSS, 이미지, 글꼴 등). Django에서는 배포 프로세스 중에 공개 디렉터리에만 "수집"됩니다.
개발 모드( python manage.py runserver )에서 Django는 STATICFILES_FINDERS 설정을 사용하여 정적 파일을 검색합니다. 기본적으로 STATICFILES_DIRS 설정에 나열된 폴더에서 요청된 정적 파일을 찾으려고 합니다. 실패할 경우 Django는 django.contrib.staticfiles.finders.AppDirectoriesFinder 를 사용하여 파일 찾기를 시도합니다. 이 파일은 프로젝트에 설치된 모든 애플리케이션의 static 폴더를 찾습니다. 이를 통해 고유한 정적 파일과 함께 제공되는 재사용 가능한 응용 프로그램을 작성할 수 있습니다.
프로덕션에서는 Nginx와 같은 독립 실행형 웹 서버를 사용하여 정적을 제공합니다. 웹 서버는 Django 프로젝트 응용 프로그램 구조 또는 정적 파일이 배포되는 폴더에 대해 아무 것도 모릅니다. 다행히 Django는 STATICFILES_FINDERS 를 살펴보고 응용 프로그램 static 에서 모든 정적 파일을 복사하는 수집 정적 관리 명령 python manage.py collectstatic 을 제공합니다. STATICFILES_DIRS 에 나열된 폴더 및 폴더를 STATIC_ROOT 설정에서 지정한 디렉토리로 이동합니다. 이를 통해 Django 개발 모드 서버와 동일한 논리를 사용하여 정적 파일 리소스를 확인할 수 있으며 웹 서버용으로 모든 정적 파일이 한 곳에 있습니다.
프로덕션 환경에서 collectstatic 을 실행하는 것을 잊지 마십시오!
실수 번호 8: 기본 STATICFILES_STORAGE , 프로덕션의 Django 템플릿 로더
STATICFILES_STORAGE
프로덕션 환경 자산 관리에 대해 이야기합시다. "자산은 만료되지 않음" 정책을 사용하면 최상의 사용자 경험을 제공할 수 있습니다(자세한 내용은 여기 참조). 이는 모든 정적 파일이 웹 브라우저에서 몇 주, 몇 달 또는 몇 년 동안 캐시되어야 함을 의미합니다. 즉, 사용자는 자산을 한 번만 다운로드해야 합니다!
멋지네요. Nginx 구성에서 정적 파일 폴더에 대해 몇 줄만 입력하면 됩니다. 하지만 캐시 무효화는 어떻습니까? 사용자가 당사 자산을 한 번만 다운로드할 경우 메뉴 항목의 로고, 글꼴, JavaScript 또는 텍스트 색상을 업데이트하면 어떻게 됩니까? 이를 우회하려면 배포할 때마다 정적 파일에 대해 고유한 URL과 파일 이름을 생성해야 합니다!
ManifestStaticFilesStorage를 STATICFILES_STORAGE 로 사용하고(주의, 해싱은 DEBUG=false 모드에서만 활성화됨) 위에서 설명한 collectstatic 관리 명령을 실행하여 간단히 수행할 수 있습니다. 이렇게 하면 프로덕션 웹 사이트에 대한 자산 요청 수가 줄어들고 웹 사이트가 훨씬 빠르게 렌더링됩니다.
캐시된 Django 템플릿 로더
또 다른 멋진 Django 기능은 모든 템플릿 렌더링에서 템플릿 파일을 다시 로드하고 구문 분석하지 않는 캐시된 템플릿 로더입니다. 템플릿 구문 분석은 매우 비용이 많이 드는 작업이며 많은 리소스를 사용합니다. 기본적으로 Django 템플릿은 모든 요청에서 구문 분석되지만 짧은 시간에 수천 개의 요청을 처리할 수 있는 프로덕션 중에 특히 좋지 않습니다.
이 작업을 수행하는 방법에 대한 자세한 예와 자세한 내용은 cached.Loader 구성 섹션을 확인하세요. 파일 시스템에서 구문 분석된 템플릿을 다시 로드하지 않으므로 개발 모드에서 로더를 사용하지 마십시오. 템플릿이 변경될 때마다 python manage.py startapp 을 사용하여 프로젝트를 다시 시작해야 합니다. 개발 중에는 성가실 수 있지만 프로덕션 환경에는 완벽합니다.
실수 9: 유틸리티 또는 스크립트를 위한 순수 Python 스크립트
Django는 관리 명령이라는 아주 좋은 기능을 제공합니다. 바퀴를 재발명하고 프로젝트 유틸리티를 위한 원시 Python 스크립트를 작성하는 대신 사용하십시오.
또한 Django용 사용자 정의 확장 모음인 Django Extensions 패키지를 확인하십시오. 누군가가 이미 명령을 구현했을 수도 있습니다! 이미 많은 일반적인 작업 명령이 있습니다.
실수 10번: 바퀴의 재발명
Django와 Python에는 바로 사용할 수 있는 수천 가지 솔루션이 있습니다. 고유하지 않은 것을 작성하기 전에 인터넷 검색을 시도하십시오. 이미 존재하는 기능이 풍부한 솔루션이 있을 수 있습니다.
일을 단순하게 만드십시오. 구글 먼저! 양질의 패키지를 찾으면 프로젝트를 설치, 구성, 확장 및 통합하고 기회가 있을 때 오픈 소스에 기여하십시오.
먼저 Django용 공개 패키지 목록은 다음과 같습니다.
- Django 매크로 URL을 사용하면 매크로를 사용하여 Django 애플리케이션에서 URL 패턴을 쉽게 작성하고 읽을 수 있습니다.
- Django Templates Names는 CBV 템플릿 이름을 쉽게 표준화할 수 있는 작은 믹스인입니다.
- django-split-settings를 사용하면 Django 설정을 여러 파일과 디렉터리로 구성할 수 있습니다. 설정을 쉽게 재정의하고 수정합니다. 설정 파일 경로에 와일드카드를 사용하고 설정 파일을 선택 사항으로 표시합니다.
자신을 반복하지 마십시오 (DRY)!
저는 DRY 방법론을 정말 좋아합니다. 그렇기 때문에 Django 스켈레톤을 바로 사용할 수 있는 정말 깔끔한 기능을 갖춘 편리한 도구로 만들었습니다.
- 컨테이너 목록을 쉽게 오케스트레이션할 수 있는 docker-compose에서 관리하는 개발/프로덕션용 도커 이미지.
- 프로덕션 배포를 위한 Simple Fabric 스크립트.
- 기본 및 로컬 소스에 대한 설정이 포함된 Django 분할 설정 패키지에 대한 구성입니다.
- 프로젝트에 통합된 Webpack - Django는
collectstatic명령으로dist폴더만 수집합니다. - 프로덕션에서 캐시 가능한 Django 템플릿, 해시된 정적 파일, 통합 디버그 도구 모음, 로깅 등과 같은 모든 기본 Django 설정 및 기능을 구성했습니다.
다음 프로젝트를 위해 처음부터 바로 사용할 수 있는 Django Skeleton이며 프로젝트를 부트스트랩하여 많은 시간을 절약할 수 있기를 바랍니다. Webpack에는 최소한의 기본 구성이 있지만 .scss 파일을 처리하도록 미리 구성된 SASS도 설치되어 있습니다.
