Widoki klasy w Django

głosy
48

Django widok wskazuje funkcję, która może być problem, jeśli chcesz zmienić tylko trochę funkcjonalności. Tak, mogę mieć milion słów kluczowych argumentów, a nawet więcej, jeśli oświadczenia w funkcję, ale myślałem raczej podejścia obiektowego.

Na przykład, mam stronę, która wyświetla użytkownikowi. Ta strona jest bardzo podobna do strony, który wyświetla grupę, ale to nie jest jeszcze tak podobne do po prostu użyć innego modelu danych. Grupa posiada również członków itp ...

Jednym ze sposobów byłoby wskazać widoki metod klasy, a następnie rozszerzyć tę klasę. Czy ktoś próbował tego podejścia lub ma inny pomysł?

Utwórz 03/08/2008 o 16:55
źródło użytkownik
W innych językach...                            


9 odpowiedzi

głosy
41

Mam tworzone i wykorzystywane własnych klas generycznych widok, definiując __call__więc instancją klasy jest wymagalne. Naprawdę to lubie; natomiast ogólne widoki Django umożliwiają dostosowywanie przez jakiś argumentów kluczowych, OO ogólne widoki (jeśli ich zachowanie jest podzielony na kilka odrębnych metod) może mieć dużo bardziej drobnoziarnista poprzez dostosowanie podklasy, która pozwala mi powtarzać wiele mniej. (I znudzi przepisywanie tego samego tworzenia / aktualizacji widok logiczny każdej chwili muszę podkręcić coś rodzajowe widoki Django nie bardzo na to pozwala).

Mam pisał jakiś kod na djangosnippets.org .

Jedynym minusem widzę jest proliferacja wewnętrznych wywołań metod, które mogą wpłynąć na wydajność nieco. Nie sądzę, że jest to dużo troski; to rzadkie, że wykonanie kodu Python byłby to wąskim gardłem wydajności w aplikacji internetowej.

UPDATE : własne Django widoki generyczne są teraz klasa oparte.

UPDATE : FWIW, ja zmieniłem zdanie na temat poglądów opartych na klasach, ponieważ ta odpowiedź została napisana. Po wykorzystaniu ich w znacznym stopniu na kilka projektów, czuję, że prowadzą do kodu, który jest satysfakcjonująco DRY pisać, ale bardzo trudne do odczytania i utrzymać później, ponieważ funkcjonalność jest rozłożone tak wielu różnych miejscach, i podklasy są tak zależne na każdy szczegół realizacji tych superklas i wstawek. Teraz czuję, że TemplateResponse i zobacz dekoratorzy jest lepszym rozwiązaniem dla rozkładających widoku kodu.

Odpowiedział 29/08/2008 o 05:29
źródło użytkownik

głosy
13

Musiałem użyć poglądy oparte klasy, ale chciałem, aby móc korzystać z pełnej nazwy klasy w moim URLconf bez konieczności zawsze instancję klasy widoku przed użyciem. Co pomogło mi było zaskakująco prosty metaklasa:

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)

Mogę teraz obie instancje klasy widoku i użyć wystąpień jako widok funkcji, czy mogę po prostu wskazać mój URLconf do mojej klasy i mieć instancję metaklasa (i call) klasy widoku dla mnie. To działa, sprawdzając pierwszy argument __call__- jeśli to jest HttpRequest, to musi być rzeczywiste żądania HTTP, ponieważ byłoby nonsensem attept do instancji klasy widoku z HttpRequestinstancji.

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'),
)

(I napisali fragment o tym w http://djangosnippets.org/snippets/2041/ )

Odpowiedział 27/05/2010 o 14:02
źródło użytkownik

głosy
9

Jeśli jesteś po prostu wyświetlania danych z modeli, dlaczego nie wykorzystać Django widoki generyczne ? Są one zaprojektowane, aby dać Ci łatwe pokazują dane z modelu bez konieczności napisać swój własny pogląd i rzeczy o mapowania URL paramaters poglądów, pobierania danych, prowadzenia spraw EDGE, wyjście renderingu itp

Odpowiedział 07/08/2008 o 11:44
źródło użytkownik

głosy
3

Zawsze można utworzyć klasę, przesłonić __call__funkcję, a następnie wskaż plik URL do instancji klasy. Można spojrzeć na FormWizard klasy, aby zobaczyć, jak to jest zrobione.

Odpowiedział 26/08/2008 o 12:38
źródło użytkownik

głosy
2

Chyba, że ​​chcesz coś zrobić mały kompleks, stosując ogólne widoki są do zrobienia. Są one znacznie bardziej wydajne niż wskazuje ich nazwa, a jeśli jesteś po prostu wyświetla rodzajowe widoki modelu danych będzie wykonać zadanie.

Odpowiedział 11/08/2008 o 23:59
źródło użytkownik

głosy
2

Brzmi dla mnie jak starasz się połączyć rzeczy, które nie powinny być łączone. Jeśli trzeba zrobić inną obróbkę w widoku w zależności czy jest to użytkownik lub grupa obiektów starasz się patrzeć na to należy użyć dwóch różnych funkcji widoku.

Z drugiej strony nie może być wspólne idiomy, że chcesz, aby wyodrębnić z twoich poglądów object_detail typu ... może można użyć dekorator lub tylko funkcje pomocnicze?

-Dan

Odpowiedział 03/08/2008 o 18:40
źródło użytkownik

głosy
1

Można użyć Django widoki generyczne. można łatwo osiągnąć pożądanej funkcjonalności gruntowne Django widoki generyczne

Odpowiedział 08/10/2014 o 06:53
źródło użytkownik

głosy
1

Widoki generyczne zwykle będzie droga, ale ostatecznie jesteś wolny do obsługi adresów URL jednak chcesz. FormWizard robi rzeczy w sposób, na bazie klasy, podobnie jak niektóre aplikacje dla REST API.

Zasadniczo z adresem URL podano kilka zmiennych i miejsce świadczenia wywoływalnym, co wywoływalnym podasz jest całkowicie do Ciebie - standardowym sposobem jest zapewnienie funkcji - ale ostatecznie Django stawia żadnych ograniczeń w tym co robisz.

Zgadzam się, że jeszcze kilka przykładów, jak to zrobić, byłoby dobrze, FormWizard jest prawdopodobnie miejscem do rozpoczęcia chociaż.

Odpowiedział 23/09/2008 o 20:05
źródło użytkownik

głosy
1

Jeśli chcesz podzielić się wspólną funkcjonalność między stronami Proponuję spojrzeć na niestandardowych znaczników. Są dość łatwe do tworzenia i są bardzo wydajne.

Ponadto, szablony mogą rozciągać się od innych szablonów . To pozwala mieć szablon bazowy, aby skonfigurować układ strony i podzielić się tym między innymi szablony, które wypełniają luki. Szablony można zagnieżdżać do dowolnej głębokości; pozwala określić układ na oddzielnych grup powiązanych stron w jednym miejscu.

Odpowiedział 26/08/2008 o 12:30
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more