문제

장고 뷰 포인트는 기능을 약간만 변경하려는 경우 문제가 될 수 있는 기능을 가리킵니다.예, 함수에 백만 개의 키워드 인수와 더 많은 if 문이 있을 수 있지만 객체 지향 접근 방식에 더 가깝다고 생각했습니다.

예를 들어, 사용자를 표시하는 페이지가 있습니다.이 페이지는 그룹을 표시하는 페이지와 매우 유사하지만 다른 데이터 모델을 사용하는 것과는 여전히 유사하지 않습니다.그룹에도 멤버가 있습니다.

한 가지 방법은 클래스 메서드에 대한 뷰를 가리킨 다음 해당 클래스를 확장하는 것입니다.누구든지 이 접근 방식을 시도했거나 다른 아이디어가 있습니까?

도움이 되었습니까?

해결책

나는 내 자신의 일반 뷰 클래스를 만들고 사용했습니다. __call__ 따라서 클래스의 인스턴스를 호출할 수 있습니다.난 정말 좋아;Django의 일반 뷰는 키워드 인수를 통해 일부 사용자 정의를 허용하는 반면, OO 일반 뷰(동작이 여러 개의 별도 메소드로 분할된 경우)는 서브클래싱을 통해 훨씬 더 세분화된 사용자 정의를 가질 수 있으므로 반복할 필요가 훨씬 줄어듭니다.(Django의 일반 뷰가 허용하지 않는 것을 조정해야 할 때마다 동일한 생성/업데이트 뷰 로직을 다시 작성하는 데 지쳤습니다.)

나는에 몇 가지 코드를 게시했습니다. djangosnippets.org.

내가 본 유일한 실제 단점은 내부 메서드 호출이 급증하여 성능에 어느 정도 영향을 미칠 수 있다는 것입니다.나는 이것이 그다지 걱정거리가 아니라고 생각합니다.Python 코드 실행으로 인해 웹 앱의 성능 병목 현상이 발생하는 경우는 거의 없습니다.

업데이트:장고 자신의 일반적인 견해 이제 클래스 기반입니다.

업데이트:FWIW, 이 답변이 작성된 이후 클래스 기반 견해에 대한 의견이 변경되었습니다.몇 가지 프로젝트에서 광범위하게 사용한 후에는 기능이 매우 다양한 위치에 분산되어 있고 하위 클래스가 매우 종속적이기 때문에 작성하기에는 만족스러울 정도로 DRY하지만 나중에 읽고 유지 관리하기가 매우 어려운 코드로 이어지는 경향이 있다고 느꼈습니다. 슈퍼클래스와 믹스인의 모든 구현 세부 사항에 대해 설명합니다.나는 이제 그것을 느낀다 템플릿응답 뷰 데코레이터는 뷰 코드 분해에 대한 더 나은 답변입니다.

다른 팁

클래스 기반 뷰를 사용해야 했지만, 사용하기 전에 항상 뷰 클래스를 인스턴스화할 필요 없이 URLconf에서 클래스의 전체 이름을 사용할 수 있기를 원했습니다.나에게 도움이 된 것은 놀랍도록 간단한 메타클래스였습니다.

class CallableViewClass(type):
    def __call__(cls, *args, **kwargs):
        if args and isinstance(args[0], HttpRequest):
            instance = super(CallableViewClass, cls).__call__()
            return instance.__call__(*args, **kwargs)
        else:
            instance = super(CallableViewClass, cls).__call__(*args, **kwargs)
            return instance


class View(object):
    __metaclass__ = CallableViewClass

    def __call__(self, request, *args, **kwargs):
        if hasattr(self, request.method):
            handler = getattr(self, request.method)
            if hasattr(handler, '__call__'):
                return handler(request, *args, **kwargs)
        return HttpResponseBadRequest('Method Not Allowed', status=405)

이제 뷰 클래스를 인스턴스화하고 인스턴스를 뷰 함수로 사용할 수 있습니다. 또는 간단히 URLconf를 내 클래스로 지정하고 메타클래스가 뷰 클래스를 인스턴스화(및 호출)하도록 할 수 있습니다.이것은 첫 번째 인수를 확인하여 작동합니다. __call__ – 만약에 HttpRequest, 뷰 클래스를 인스턴스화하려고 시도하는 것은 말도 안 되기 때문에 실제 HTTP 요청이어야 합니다. HttpRequest 사례.

class MyView(View):
    def __init__(self, arg=None):
        self.arg = arg
    def GET(request):
        return HttpResponse(self.arg or 'no args provided')

@login_required
class MyOtherView(View):
    def POST(request):
        pass

# And all the following work as expected.
urlpatterns = patterns(''
    url(r'^myview1$', 'myapp.views.MyView', name='myview1'),
    url(r'^myview2$', myapp.views.MyView, name='myview2'),
    url(r'^myview3$', myapp.views.MyView('foobar'), name='myview3'),
    url(r'^myotherview$', 'myapp.views.MyOtherView', name='otherview'),
)

(저는 이에 대한 스니펫을 게시했습니다. http://djangosnippets.org/snippets/2041/)

단순히 모델의 데이터를 표시하는 경우 Django 일반 뷰?뷰에 대한 URL 매개변수 매핑, 데이터 가져오기, 엣지 케이스 처리, 출력 렌더링 등에 대한 내용과 자체 뷰를 작성하지 않고도 모델의 데이터를 쉽게 표시할 수 있도록 설계되었습니다.

언제든지 클래스를 생성하고 __call__ 함수를 호출한 다음 URL 파일을 클래스의 인스턴스로 지정합니다.다음을 살펴보실 수 있습니다. 양식 마법사 이것이 어떻게 이루어지는지 알아보는 수업입니다.

합치면 안 될 것들을 합치려는 것 같군요.보고자 하는 개체가 사용자인지 그룹인지에 따라 보기에서 다른 처리를 수행해야 하는 경우 두 가지 다른 보기 기능을 사용해야 합니다.

반면에 object_detail 유형 뷰에서 추출하고 싶은 일반적인 관용구가 있을 수 있습니다.아마도 데코레이터나 도우미 기능을 사용할 수 있을까요?

-단

약간 복잡한 작업을 수행하려는 경우가 아니라면 일반 뷰를 사용하는 것이 좋습니다.이름이 암시하는 것보다 훨씬 더 강력하며, 모델 데이터만 표시하는 경우 일반 뷰가 해당 작업을 수행합니다.

일반적으로 일반 보기를 사용하는 것이 좋지만 궁극적으로 원하는 대로 URL을 자유롭게 처리할 수 있습니다.FormWizard는 일부 RESTful API용 앱과 마찬가지로 클래스 기반 방식으로 작업을 수행합니다.

기본적으로 URL을 사용하면 콜러블을 제공할 수 있는 많은 변수와 장소가 제공되며, 콜러블을 제공하는 것은 전적으로 귀하에게 달려 있습니다. 표준 방법은 함수를 제공하는 것입니다. 그러나 궁극적으로 Django는 귀하가 수행하는 작업에 제한을 두지 않습니다.

나는 이 작업을 수행하는 방법에 대한 몇 가지 예가 더 좋을 것이라는 데 동의합니다. 하지만 FormWizard가 아마도 시작하는 곳일 것입니다.

페이지 간에 공통 기능을 공유하려면 사용자 정의 태그를 살펴보는 것이 좋습니다.그들은 꽤 만들기 쉽다, 매우 강력합니다.

또한, 템플릿은 다른 템플릿에서 확장될 수 있습니다..이를 통해 페이지 레이아웃을 설정하고 공백을 채우는 다른 템플릿 간에 이를 공유할 수 있는 기본 템플릿을 가질 수 있습니다.템플릿을 원하는 깊이로 중첩할 수 있습니다.한 곳에서 관련 페이지의 별도 그룹에 대한 레이아웃을 지정할 수 있습니다.

Django 일반 뷰를 사용할 수 있습니다.Django 일반 뷰를 통해 원하는 기능을 쉽게 얻을 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top