Frage

Ich ziehe aus einem PHP-Hintergrund in Django Entwicklung über Python, vor allem im Interesse eine MVC der Bekämpfung (oder MVT), dass ich fühle mich am meisten Sinn macht, obwohl in diesem Muster, das ich angefangen habe viel zu bemerken, wiederholter Code in meinen Ansichten.

Zum Beispiel protokolliert, wenn in Ich habe Informationen über den Benutzer, dass ich auf jeder Seite angezeigt werden soll, wenn auch bei der Verwendung von render_to_response und in jeder Ansicht dies erforderlich ist, ich habe die Informationen zu packen und an die render_to_response Funktion übergeben.

Ich frage mich, was der effizienteste Weg sein würde, auf dem doppelten Code zu reduzieren, die im Wesentlichen in allen Ansichten in einer bestimmten Anwendung erforderlich wäre.

Vielen Dank im Voraus.

War es hilfreich?

Lösung

Persönlich bin ich ein großer Fan von Dekorateure, die eine Python-Funktion, die nicht spezifisch für Django ist. Dekorateure sind die perfekte syntaktischer Zucker oben auf Funktionen höherer Ordnung, und sie sind besonders nützlich für die vorformulierten in Aussicht zu reduzieren - Sie schnell eine generali Wrapper-Funktion definieren können, in dem Sie den repetitiven Code für die einfache Wiederverwendung und bequem ein setzen können -stop Refactoring.

Es ist wahrscheinlich einfacher, Ihnen zu zeigen, als erklären, wie sie funktionieren. Hier ist eine vereinfachte Ansicht Beispiel:

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"),
    }))

... aber dann sagen Sie diese Seiten muss der Benutzer machen wollte eingeloggt Sie können Login-Code hinzufügen, etwa so:.

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"),
        }))

..., die vor allem größer und repetitiven zu bekommen beginnen, auch für ein konstruiertes Beispiel. Sie können Ihre Funktionen schlank wieder mit Dekorateure, wie so machen:

von Dekorateur Import Dekorateur

@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):
    (...)

Was passiert, ist die Dekorateur Funktion zum Zeitpunkt der Funktionsdefinition ausgeführt. Die ‚f‘ in meinem Beispiel ist eine Aufgabe, die die Funktion, dass der Dekorateur angewandt wird, die Sie in unending Weise manipulieren können.

Dies erfordert die Dekorateur Bibliothek , die auf PyPI frei ist, so viele gute Python Häppchen sind , du wirst es finden.

Sie brauchen nicht auf die diese Bibliothek zu schreiben Dekorateur Funktionen, aber es ist hilfreich, vor allem am Anfang. Sie können eine ganze Menge mehr tun - jede aufrufbare kann ein Dekorateur sein; Sie können Klassenmethoden und abfangen die self Variable dekorieren; Dekorateure kann angekettet werden, etwa so:

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

Ich werde die Erforschung lassen, was man mit so einfachen Funktion höherer Ordnung manpipulation für Sie tun können, sollte dieser Begriff wetzen Ihren Appetit. Ich habe viele weitere Beispiele auch, für Sie oder andere merkwürdige neue Python-Fans. Viel Glück.

Andere Tipps

kapseln die gemeinsamen Code in einer Funktion und rufen Sie es aus verschiedenen Blickwinkeln. Klingt trivial, aber es ist die Lösung für 99% dieser Bedürfnisse.

Für eine bestimmte Antwort, werden Sie ein konkreteres Beispiel für den Code zeigen, müssen Sie ausführen möchten.

Es gibt zwei Möglichkeiten für gemeinsame Inhalte abstrahiert werden.

Context Prozessoren sind am besten für Datenbits vorbei dass Sie wissen, müssen Sie auf jeden einzelnen Blick.

Template-Tags - vor allem der Aufnahme Tags - sind nützlich zum Rendern getrennte Bereiche der Seite, die das gleiche auf mehrere Vorlagen werden.

Auch vergessen Sie nicht über generischen Ansichten ! In 90% der Fälle können Sie wickeln Object_List oder object_detail und sparen Sie sich einige Code.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top