초보자 : 앱이 Django에서 어떻게 상호 작용하는지 이해하려고합니다.
-
20-08-2019 - |
문제
방금 Django 튜토리얼을 통해 두 번째로 작업을 수행했으며 지금은 훨씬 더 명확하게 이해하고 있습니다. 그러나 사이트 내부의 앱이 서로 어떻게 상호 작용하는지 여전히 불분명합니다.
예를 들어, 블로그 응용 프로그램을 작성한다고 가정 해 봅시다 (분명히 인기있는 활동). 블로그 게시물과 의견은 함께 진행되는 경향이 있지만 Djano 개발의 일반적인 철학과 마찬가지로 별도의 앱으로 내장해야 할 정도로 뚜렷합니다.
다음 예를 고려하십시오. 실제로 나는 웹에 이미 존재하는 좋은 코드로서 댓글 앱을 직접 작성하지는 않지만 이는 데모/연습 목적입니다.
mysite/blog/models.py
from django.db import models
class post(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=200)
content = models.TextField()
mysite/comments/models.py
from django.db import models
from mysite.blog.models import post
class comment(models.Model):
id = models.AutoField()
post = models.ForeignKey(post)
author = models.CharField(max_length=200)
text = models.TextField()
내가 위에서 쓴 내용은 다른 앱에서 모델을 가져 와서 외국 키로 설정하는 것입니다. Django 앱이 어떻게 상호 작용하는지? 아니면 상호 작용하는 사이트를 구성하는 앱에 대해 다른/더 나은 방법이 있습니까?
업데이트
하나의 응답으로 권장 사항에 따라 Contrib.ContentTypes에 대한 문서를 읽고 있습니다. 이것을 올바르게 읽으면 예제 댓글 앱을 다시 작성할 수 있습니다.
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contentypes import generic
class comment(models.Model):
id = models.AutoField()
author = models.CharField(max_length=200)
text = models.TextField()
content_type = models.ForeignKey(ContentType)
content_object = generic.GenericForeignKey(content_type, id)
이것이 맞습니까?
해결책
Django의 내장을 살펴보십시오 ContentTypes 프레임 워크:
django.contrib.contenttypes
응용 프로그램을 독립형 단위로 개발할 수 있습니다. 이것이 Django 개발자가 Django의 내장을 허용하는 데 사용한 것입니다. 주석 프레임 워크 프로젝트의 모든 모델에 의견을 첨부합니다.
예를 들어, 각 사용자가 블로그 게시물, 이미지 또는 사용자 프로필에 "좋아하는"스타를 남겨 두는 것과 같이 다른 유형의 다른 콘텐츠 객체에 "첨부"하려는 콘텐츠 객체가있는 경우 Favorite
a 일반 관계 필드 그렇게 :
from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
class Favorite(models.Model):
user = models.ForeignKey(User)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
이런 식으로 당신은 a를 추가 할 수 있습니다 Favorite
모든 사용자에서 프로젝트의 모든 모델에 이르기까지 스타. 수신자 모델 클래스를 통해 API 액세스를 추가하려면 반전 제네릭 관계 필드 수신자 모델에서 (이것은 당신이 피하고 싶다고 말한 두 모델을 "커플 링"하거나 Favorite
모델과 모델 content_type
그리고 object_id
수신자 인스턴스의 참조 공식 문서 예를 들어.
다른 팁
"내가 위에서 쓴 내용은 다른 앱에서 모델을 가져 와서 외국 키로 설정하는 것입니다. Django 앱이 어떻게 상호 작용하는지?"
네. 나를 위해 일합니다.
우리는 그들 사이에서 앞뒤로 빌려주는 약 10 개의 응용 프로그램이 있습니다.
이것은 단위 테스트 스크립트에서 일종의 종속성으로 이어집니다.
이렇게 보인다.
"소유권". 다른 응용 프로그램이 의존하는 핵심 소유권 개념을 정의하는 간단한 데이터 소유권 응용 프로그램이 있습니다. 여기에는 몇 가지 간단한 테이블이 있습니다.
"물건". [실제 이름이 아님]. 우리의 Thing Application에는 다른 사용자 그룹이 소유 한 데이터 요소가 있습니다. 실제로이 앱의 모델에는 몇 가지 복잡한 테이블이 있습니다. "소유권"에 따라 다릅니다.
"테이블". [실제 이름이 아님]. 일부 사용자는 상당히 복잡한 오프라인 모델 (아마도 스프레드 시트 포함)을 생성하고 "테이블"에 해당 모델링 결과를 업로드합니다. 여기에는 상당히 복잡한 테이블 클러스터가 있습니다. "소유권"에 따라 다릅니다.
"결과". [실제 이름이 아님]. 우리의 결과는 소유자가있는 것들을 기반으로합니다. 결과는 사물과 테이블을 기반으로하며 고객 요청에 대한 응답입니다. 이것은 너무 복잡하지 않으며 아마도 두 ~ 3 개의 핵심 테이블 만 있습니다. "사물"과 "테이블"에 따라 다릅니다. 아니요, 완전히 독립형은 아닙니다. 그러나 그것은 다른 것보다 더 많은 변화가 발생합니다. 그것이 분리 된 이유입니다.
"처리". 우리는 큰 배치 작업을 예약하고 모니터링합니다. 이것은이 응용 프로그램에 있습니다. 정말 일반적이며 다양한 방식으로 사용될 수 있습니다. 그것은 완전히 혼자 서 있습니다.
"환영하다". 우리는 대부분 정적 페이지를 보여주는 "환영"앱이 있습니다. 테이블이 너무 많지 않습니다. 그러나 첫 번째가 너무 복잡했기 때문에 그것은 두 번째 화신입니다. 그것은 완전히 혼자 서 있습니다.
종속 앱 간의 유일한 관계는 일부 테이블 이름입니다. 해당 테이블 (및 키)을 보존하는 한 적합한대로 다른 앱을 재 배열 할 수 있습니다.
일부 앱이 다른 앱에 의존하게하는 것은 잘못된 것이 없습니다 (IMHO). 결국, 앱은 일련의 모델에서만 작동하는 것입니다. 어떤 앱이 어떤 앱에 의존하는지 항상 알고 있어야합니다 (해당 종속성 맵이라고 부를 수 있다고 생각합니다).
ContentTypes 프레임 워크와 느슨한 커플 링을 얻을 수 있습니다. 이를 통해 앱을 휴대용/플러그 가능하지만 여전히 다른 응용 프로그램과 통합 할 수 있습니다.
주석 앱 (예, 휠을 재발 명했습니다)을 썼는데, 이는 다른 애플리케이션에 통합 될 수 있으며, 주석을 게시 해야하는 페이지의 템플릿에 몇 줄이 (사용자 정의 태그를 사용).
모델 "스레드"를 다른 모델에 밀어 넣기를 원한다고 가정 해 봅시다. 아이디어는 E 일반적인 외국 키를 작성하고 (이에 대한 Django 문서 참조), 객체를 가져 와서 해당하는 "스레드"를 반환하는 작은 함수를 작성하고 필요한 경우 하나를 작성하고 사용자 정의 템플릿 태그를 작성하는 것입니다. 그 기능을 사용합니다 {% get_thread for arbitrary_object as thread %}
. 모든 게시물은 모든 유형 일 수있는 객체와 관련된 스레드와 관련이 있습니다.
"스레드"객체를 일종의 프록시로 생각할 수 있으므로 게시물이 특정 "기사"또는 "블로그 게시물"과 관련이있는 대신 스레드와 관련이 있습니다. , 무엇 ~이다 스레드인가요? 그것은 단지 게시물 모음 일뿐입니다. 그런 다음 스레드는 유형에 관계없이 모든 객체와 관련 될 수 있습니다. (그보다 더 많은 일이지만, ANON을 허용/허용하는 것과 같은 추가 정보를 보유 할 수 있습니다. 게시물, 페이지 폐쇄/오프닝 댓글 등).)
편집하다
컨텐츠 유형 프레임 워크를 사용하여 일반적인 외국 키를 만드는 방법은 다음과 같습니다.
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
class Thread( models.Model ):
object_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
object = generic.GenericForeignKey('object_type', 'object_id')
Django가 모든 객체가 구현한다고 가정하는 암시 적 "공통"인터페이스를 악용하여보다 "투명"으로 만들 수 있습니다.
#inside the Thread class:
def __unicode__(self):
return unicode(self.object)
def get_absolute_url(self):
return self.object.get_absolute_url()
코드가 정확해 보입니다. 나는 게시물과 댓글을 블로그 그래도 앱. 나는 이것이 말하지 않는다 그만큼 Django Way이지만 이러한 모델은 동일한 앱에있을 정도로 가깝습니다.
프로젝트를 나누는 방법
나는 앱을 분리 할 것이다.
- 나는 그것을 방지 할 수있는 디자인을 계획 할 계획이다. (그리고 느슨한 커플 링을 시도하십시오)
- (큰 프로젝트의 경우) 프로젝트의 주요 섹션으로 구성됩니다.
반면에; 많은 작은 앱 (예 : 단일 모델 및 두 개의보기와 같은)을 갖는 것은 IMHO를 읽고 유지하기가 어렵습니다.
앱이 상호 작용하는 방법
이것은 프로젝트 유형과 앱의 유형에 따라 다릅니다. 예를 들어 앱이 다른 앱의 참조 및 참조를 사용하는 다른 앱 (예 : 일반적인)에 암시 적으로 의존하는 경우 허용됩니다. 이 경우 두 번째 앱은 단독으로 설치 될 수 있지만 첫 번째 앱에는 두 번째 앱이 필요합니다.
주석 앱과 같이 앱을 재사용 가능하고 일반적인 앱으로 만들려면 일부 설정 메커니즘을 통합해야 할 수도 있습니다. 아마도 새로운 설정 또는 추가 URL 구성 또는 모델의 특수 지시 사항/방법 ... django.contrib.admin
이것에 대한 좋은 예입니다.
그래도 앱이 필요하지 않은 경우 상호 작용해서는 안됩니다. 불필요한 커플 링을 피하기 위해 앱을 설계하는 것은 매우 유용합니다. 앱의 유연성을 향상시키고 더 관리하기 쉽지만 통합 비용이 더 높을 수 있습니다.