Domanda

mi sto muovendo da un background di PHP nello sviluppo Django via pitone, in gran parte per il bene di affrontare un MVC (o MVT) che mi sento rende più senso, anche se in questo modello che ho iniziato a notare un sacco di codice ripetuto nel mio punto di vista.

Per esempio, quando loggato ho informazioni riguardanti l'utente che vorrei apparire su ogni pagina, anche se quando si utilizza render_to_response e in ogni vista questo è richiesto devo prendere le informazioni e passarlo alla funzione render_to_response.

Mi chiedo quale sarebbe il modo più efficace per ridurre il codice duplicato che sarebbe in sostanza essere richiesta in tutte le viste in una particolare applicazione.

Grazie in anticipo.

È stato utile?

Soluzione

Personalmente sono un grande fan di decoratori, che sono una caratteristica di Python che non è specifico per Django. Decoratori sono lo zucchero sintattico perfetta sulla cima di funzioni di ordine superiore, e sono particolarmente utili per ridurre boilerplate in vista - è possibile definire rapidamente una funzione wrapper generalizzata, in cui è possibile inserire il codice ripetitivo per un facile riutilizzo e uno pratico refactoring -stop.

E 'probabilmente più facile visualizzare quanto spiegano come funzionano. Ecco un esempio di visualizzazione semplificata:

def listpage(request):
    return HttpResponse(render_to_string("itemlist.html", {
        "items": Item.objects.filter(visible=True).order_by("-modifydate")
    }))

def itemlist_tags(request, tags):
    return HttpResponse(render_to_string("itemlist.html", {
        "items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
    }))

... ma poi dicono di voler fare queste pagine richiedono all'utente di accedere Si potrebbe aggiungere il codice di accesso in questo modo:.

def listpage(request):
    if not request.user.is_authenticated():
        return f(request, *args, **kwargs)
    else:
        return HttpResponse(render_to_string("itemlist.html", {
            "items": Item.objects.filter(visible=True).order_by("-modifydate")
        }))

def itemlist_tags(request, tags):
    if not request.user.is_authenticated():
        return f(request, *args, **kwargs)
    else:
        return HttpResponse(render_to_string("itemlist.html", {
            "items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
        }))

..., che sta iniziando a ottenere in particolare più grande e ripetitivo, anche per un esempio forzato. È possibile effettuare le funzioni sottili di nuovo con decoratori, in questo modo:

da decoratore import decoratore

@decorator
def loginrequired(f, request, *args, **kwargs):
    if request.user.is_authenticated():
        return f(request, *args, **kwargs)
    else:
        return HttpResponseRedirect("/")

@loginrequired
def listpage(request):
    return HttpResponse(render_to_string("itemlist.html", {
        "items": Item.objects.filter(visible=True).order_by("-modifydate")
    }))

    @loginrequired
def itemlist_tags(request, tags):
    return HttpResponse(render_to_string("itemlist.html", {
        "items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
    }))

@loginrequired
def another_such_function(request):
    (...)

@loginrequired
def and_again(request):
    (...)

Quello che succede è la funzione decoratore viene eseguita al momento della definizione della funzione. Il 'f' nel mio esempio è un oggetto che rappresenta la funzione che il decoratore viene applicato a, che è possibile manipolare in modi senza fine.

Ciò richiede la decoratore biblioteca, che è libero su PyPI come sono molti buoni bocconi pitone , lo troverai.

Non è necessario l'questa libreria per scrivere funzioni decoratore, ma è utile, soprattutto all'inizio. Essi possono fare molto di più - qualsiasi callable può essere un decoratore; è possibile decorare i metodi della classe e intercettare la variabile self; decoratori possono essere concatenati up, in questo modo:

@second
@first
def originalfunction(*args):
    (...)

Lascio l'esplorazione di ciò che si può fare con tale funzione semplice di ordine superiore manpipulation per te, dovrebbe questa nozione stuzzicare l'appetito. Ho molti altri esempi come pure, per voi o altri nuovi appassionati pitone curiosi. Buona fortuna.

Altri suggerimenti

incapsulare il codice comune in una funzione e chiamare da diversi punti di vista. Sembra banale, ma è la soluzione per il 99% di tali esigenze.

Per una risposta più specifica, dovrete mostrare un esempio più concreto del codice che si desidera eseguire.

Ci sono due modi principali per astrarre il contenuto comune.

processori di contesto

sono migliori per il passaggio bit di dati che si sa è necessario su ogni singola vista.

Tag modello - specialmente i tag di inclusione - sono utili per il rendering aree separate della pagina che sarà lo stesso su diversi modelli.

Inoltre, non dimenticare di viste generiche ! Nel 90% dei casi si può avvolgere Object_List o object_detail e risparmiare un po 'di codice.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top