Vra

Django sienings dui op 'n funksie, wat 'n probleem kan wees as jy net 'n bietjie funksionaliteit wil verander.Ja, ek kan miljoen sleutelwoordargumente en selfs meer as stellings in die funksie hê, maar ek het meer gedink aan 'n objekgeoriënteerde benadering.

Ek het byvoorbeeld 'n bladsy wat 'n gebruiker vertoon.Hierdie bladsy is baie soortgelyk aan bladsy wat 'n groep vertoon, maar dit is steeds nie so soortgelyk om net 'n ander datamodel te gebruik nie.Groep het ook lede ens...

Een manier sou wees om standpunte na klasmetodes te wys en dan daardie klas uit te brei.Het iemand hierdie benadering probeer of het enige ander idee?

Was dit nuttig?

Oplossing

Ek het my eie generiese aansigklasse geskep en gebruik, definieer __call__ dus is 'n instansie van die klas oproepbaar.Ek hou regtig daarvan;terwyl Django se generiese sienings 'n mate van aanpassing deur middel van sleutelwoordargumente toelaat, kan OO-generiese sienings (as hul gedrag in 'n aantal afsonderlike metodes verdeel word) baie meer fyn aanpassings hê via subklassering, wat my baie minder laat herhaal.(Ek word moeg daarvoor om dieselfde skep/opdateer aansiglogika te herskryf wanneer ek iets moet aanpas wat Django se generiese sienings nie heeltemal toelaat nie).

Ek het 'n kode geplaas by djangosnippets.org.

Die enigste werklike nadeel wat ek sien, is die verspreiding van interne metode-oproepe, wat prestasie ietwat kan beïnvloed.Ek dink nie dit is baie van kommer nie;dit is selde dat Python-kode uitvoering jou prestasie-bottelnek in 'n webtoepassing sou wees.

OPDATEER:Django se eie generiese sienings is nou klasgebaseerd.

OPDATEER:FWIW, ek het my mening oor klasgebaseerde sienings verander sedert hierdie antwoord geskryf is.Nadat ek dit baie op 'n paar projekte gebruik het, voel ek dat hulle geneig is om te lei tot kode wat bevredigend DROOG is om te skryf, maar baie moeilik is om later te lees en in stand te hou, want funksionaliteit is oor soveel verskillende plekke versprei, en subklasse is so afhanklik. op elke implementeringsdetail van die superklasse en mixins.Ek voel dit nou Sjabloonantwoord en uitsigversierders is 'n beter antwoord vir die ontbinding van aansigkode.

Ander wenke

Ek moes klasgebaseerde aansigte gebruik, maar ek wou die volle naam van die klas in my URLconf kon gebruik sonder om altyd die aansigklas te instansieer voordat ek dit gebruik.Wat my gehelp het, was 'n verbasend eenvoudige metaklas:

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)

Ek kan nou beide aansigklasse instansieer en die instansies as aansigfunksies gebruik, OF ek kan bloot my URLconf na my klas wys en die metaklas die aansigklas vir my laat instansieer (en oproep).Dit werk deur die eerste argument na te gaan __call__ – as dit 'n HttpRequest, moet dit 'n werklike HTTP-versoek wees, want dit sal onsin wees om te probeer om 'n aansigklas te instansieer met 'n HttpRequest instansie.

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

(Ek het 'n brokkie hiervoor geplaas by http://djangosnippets.org/snippets/2041/)

As jy bloot data van modelle vertoon, hoekom gebruik jy nie die Django Generiese sienings?Hulle is ontwerp om jou maklik data vanaf 'n model te laat wys sonder om jou eie aansig te skryf en dinge oor die kartering van URL-parameters na aansigte, die haal van data, die hantering van randsake, die lewering van uitvoer, ens.

Jy kan altyd 'n klas skep, die ignoreer __call__ funksie en wys dan die URL-lêer na 'n instansie van die klas.Jy kan 'n blik op die FormWizard klas om te sien hoe dit gedoen word.

Klink vir my of jy dinge probeer kombineer wat nie gekombineer moet word nie.As jy verskillende verwerking in jou aansig moet doen, afhangende van of dit 'n Gebruiker- of Groepobjek is waarna jy probeer kyk, moet jy twee verskillende aansigfunksies gebruik.

Aan die ander kant kan daar algemene idiome wees wat jy uit jou object_detail tipe aansigte wil onttrek ...dalk kan jy 'n versierder of net helperfunksies gebruik?

- Dan

Tensy jy iets 'n bietjie kompleks wil doen, is die gebruik van die generiese sienings die pad om te gaan.Hulle is baie kragtiger as wat hul naam aandui, en as jy net modeldata vertoon, sal generiese aansigte die werk doen.

Generiese aansigte sal gewoonlik die pad wees om te gaan, maar uiteindelik staan ​​jy vry om URL's te hanteer soos jy wil.FormWizard doen dinge op 'n klasgebaseerde manier, net soos sommige toepassings vir RESTful API's.

Basies met 'n URL kry jy 'n klomp veranderlikes en plek om 'n oproepbare te verskaf, watter oproepbare jy verskaf is heeltemal aan jou - die standaard manier is om 'n funksie te verskaf - maar uiteindelik plaas Django geen beperkings op wat jy doen nie.

Ek stem saam dat nog 'n paar voorbeelde van hoe om dit te doen goed sal wees, FormWizard is egter waarskynlik die plek om te begin.

As jy gemeenskaplike funksionaliteit tussen bladsye wil deel, stel ek voor dat jy na pasgemaakte etikette kyk.Hulle is nogal maklik om te skep, en is baie kragtig.

Ook, sjablone kan uit ander sjablone strek.Dit laat jou toe om 'n basissjabloon te hê om die uitleg van die bladsy op te stel en om dit te deel tussen ander sjablone wat die spasies invul.Jy kan sjablone tot enige diepte nes;wat jou toelaat om die uitleg op aparte groepe verwante bladsye op een plek te spesifiseer.

Jy kan die Django Generic Views gebruik.U kan die gewenste funksionaliteit maklik bereik deur Django generiese aansigte

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top