0

Django 애플리케이션을 만드는 동안 일종의 딜레마가 발생합니다. 문제는 일반적으로 발생하는 문제가 MVC 패턴에 일반적으로 적용될 수 있다고 생각합니다. 나는 퀴즈 나 설문지를 만드는 데 사용할 수있는 Question 모델을 만들고 있습니다. Question 기본 클래스는 간단한 무료 응답 질문입니다. 객관식 질문이나 슬라이딩 스케일 질문과 같은 다양한 유형의 질문을 지원하고 싶습니다. 이러한 질문은 가능한 선택 목록과 같이 추가 필드가 추가 된 Question 기본 클래스의 하위 클래스가됩니다. 앞으로 더 많은 질문 유형을 지원하도록 내 질문 모델을 확장 할 수 있기를 바랍니다. 따라서 다형성에 의지하고 Question의 모든 하위 클래스에 대해 모델 계층과 뷰 계층간에 Question 유형의 객체를 전달할 수 있습니다. .모델 다형성과 모델 뷰 분리

내가 겪고있는 문제는보기가 그것을 렌더링하기 위해받은 질문의 유형을 알아야한다는 것입니다. 객관식 질문을하면 라디오 선택 위젯 등을 그려야합니다. 이제 모델을 더 많은 유형의 질문으로 확장하면 모델과 뷰 레이어 모두에 추가해야합니다. 이것은 Question 객체를받는 뷰가받은 질문의 하위 클래스 유형을 항상 알아야하기 때문에 다형성의 포인트를 무력화시키는 것으로 보입니다. 질문을 모델로 돌려 보내는 책임을 위임하여이 문제를 해결할 수 있습니다. Question 모델에 서브 클래스가 오버라이드하는 render_question()이라는 가상 함수가있는 경우 뷰 계층은 해당 유형의 함수를 호출하여 질문 유형에 대한 걱정없이 올바른 HTML을 출력 할 수 있습니다. 하지만 지금은 HTML 렌더링 코드가 모델과 묶여 있어야하는 문제가 있습니다.

내가 생각한 솔루션의 단점을 갖고 있지 않은 세 번째 솔루션이있을 수 있습니까? 아니면 진정으로 어려운 결정을 내려야하는 딜레마일까요?

답변

0

모델/뷰 간 분리는 데이터에서 프레젠테이션을 분리하기위한 것입니다. Question에 대한 다형성 모델 계층의 초기 설명은 실제로 유효한 접근 방식입니다.

당신이 정말로 여기에하고 싶은 것은 데이터의 계층 구조를 처리, 즉하기 위해 장고의 모델 상속을 사용하는 것을 고려되고 있습니다

BaseQuestion <- FreeQuestion, 
       MultipleChoiceQuestion, 
       SlidingScaleQuestion etc. 

그런 다음 당신이 BaseQuestion (예를 들어 질문을 렌더링 표시하는 방법을 알고있는 BaseQuestionView을 구축 할 수 있습니다 문자열, 스타일이 무엇을하지 않음)과 같은 원리 구조 사용 : DB A에서 모든 BaseQuestion 모델 인스턴스를 끌어로

BaseQuestionView <- FreeQuestionView, 
        MultipleChoiceQuestionView, 
        SlidingScaleQuestionView 

당신은 BaseQuestionView 추상적를 만들 수 있습니다 각각 FreeQuestionView, MultipleChoiceQuestionView, SlidingScaleQuestionView 서브 클래스로 구현되는 abstract render_question 메소드를 호출한다. 따라서 FreeQuestionViewFreeQuestion 모델에 대한 작업을 알고 있으며 답변 (텍스트 필드)에 위젯을 렌더링하는 방법 만 구현합니다. MultipleChoiceQuestionView은 라디오 박스 등을 렌더링하는 방법 만 구현합니다.

즉 렌더링 구현이 모델 클래스가 아닌 뷰 클래스에 있다는 점을 제외하고는 첫 번째 사례에서 제시 한 것과 거의 같습니다.

동일한 원리를 다른 방식으로 렌더링하려는 경우에도 같은 원리를 적용 할 수 있습니다.


모델 상속을 사용하면 기본 인스턴스의 하위 클래스에 도트 표기법으로 액세스 할 수 있습니다. 즉: question.freequestion. 기본 인스턴스와 연결된 FreeQuestion 인스턴스를 반환하거나 해당 클래스가 아닌 경우 Question.DoesNotExist을 발생시킵니다.

클래스 기반 뷰를 사용하면 날씨에 따라 다르게 렌더링 할 수있는 Mixins를 추가 할 수 있습니다.이 패턴은 FreeQuestion, MultipleChoiceQuestion, Python의 MRO 패턴을 사용하거나 하위 클래스로 분류 할 수 있습니다.

내가 아는 한 장고가 상속 된 모델과 상속 된 뷰 사이의 상관 관계를 자동으로 만들지는 않는다. 매핑을 직접 만들어야한다.

아마도 가장 쉬운 방법은 FreeQuestions, MultipleChoiceQuestions 등과 관련된 초기 Question QuerySet과 일치하는 모든 인스턴스를 명시 적으로 요청하고 주 렌더러에 입력하기 전에 목록에 캐스팅 한 다음 map[question.__class__]을 찾아서 믹서로부터의 렌더러 메소드 또는 기본 클래스에 질문 유형을 유지하여 클래스 매핑을 처리하지 않아도되고 DB가 이와 관련하여 도움을 줄 수 있습니다.

그러나 일반적으로 모델 동작이 동일한 클래스 (BaseQuestion을 사용하여 효과적으로 수행하는 것)에서 동적으로 변경되는 것을 원하지는 않습니다. REST를 염두에두고 디자인 할 때 특히 명시 적 URL을 명시 적 구체가 아닌 추상 유형으로 매핑하려는 경우에 특히 그렇습니다.

+0

응답 주셔서 감사합니다. 좋은 해결책 인 것 같습니다. 나는 followup을 가지고있다 :'BaseQuestionView'의 오른쪽 하위 클래스가'BaseQuestion'의 특정 인스턴스와 연관되어 있는지 어떻게 확인해야합니까? 런타임 중에'BaseQuestion'의 각 인스턴스가 인스턴스화되면, 그 질문이 인스턴스화 될 때'BaseQuestionView'의 올바른 하위 클래스 인 각 질문을 하나의 델리게이트와 연관시킵니다. 그러나이 작업을 수행하는 가장 좋은 방법은 데이터베이스 쿼리를 사용하여 채워지는 질문 목록과 함께하는 것이 확실하지 않습니다. 이 협회를 어떻게 구현 하시겠습니까? – solarein

+0

업데이트 답변보기 – astevanovic