Pergunta

Estou passando de um plano de fundo PHP para o desenvolvimento de Django via Python, principalmente para combater um MVC (ou MVT) que eu sinto que faz mais sentido, embora nesse padrão comecei a notar muito código repetido em meus pontos de vista.

Por exemplo, quando conectado, tenho informações sobre o usuário que gostaria de aparecer em todas as páginas, embora, ao usar render_to_Response e, em todas as visualizações, isso é necessário, eu tenho que pegar as informações e transmiti -las para a função render_to_Response.

Estou me perguntando qual seria a maneira mais eficiente de reduzir o código duplicado que seria necessário em todas as visualizações em um aplicativo específico.

Desde já, obrigado.

Foi útil?

Solução

Pessoalmente, sou um grande fã de decoradores, que é um recurso Python que não é específico para o Django. Os decoradores são o açúcar sintático perfeito em cima de funções de ordem superior e são especialmente úteis para reduzir o calderplate nas visualizações-você pode definir rapidamente uma função de wrapper generalizada, na qual você pode colocar o código repetitivo para facilitar a reutilização e a conveniente -Popa refatoração.

Provavelmente é mais fácil mostrar a você do que explicar como eles funcionam. Aqui está um exemplo de visualização simplificado:

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

... mas então diga que você queria fazer essas páginas exigirem que o usuário faça login. Você pode adicionar código de login como assim:

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

... que está começando a ficar notavelmente maior e repetitivo, mesmo para um exemplo artificial. Você pode fazer suas funções diminuíram novamente com os decoradores, assim:

do decorador de importação de decoradores

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

O que acontece é que a função decoradora é executada no momento da definição da função. O 'f' no meu exemplo é um objeto que representa a função a que o decorador é aplicado, ao qual você pode manipular de maneiras intermináveis.

Isso requer o Biblioteca de decoradores, que é gratuito no Pypi, assim como muitos bons pedaços de Python, você encontrará.

Você não precisa da biblioteca para escrever funções do decorador, mas é útil, especialmente no começo. Eles podem fazer muito mais - qualquer chamável pode ser um decorador; você pode decorar métodos de classe e interceptar o self variável; Os decoradores podem ser acorrentados, assim:

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

Deixarei a exploração do que você pode fazer com uma função de ordem superior tão fácil de manpipulação para você, caso essa noção aguarde seu apetite. Também tenho muitos outros exemplos, para você ou qualquer outro curioso novo aficionado em Python. Boa sorte.

Outras dicas

Encapsular o código comum em uma função e chamá -lo de diferentes visualizações. Parece trivial, mas é a solução para 99% dessas necessidades.

Para uma resposta mais específica, você terá que mostrar um exemplo mais concreto do código que deseja executar.

Existem duas maneiras principais de abstrair conteúdo comum.

Processadores de contexto são os melhores para passar de dados que você sabe que precisará em todas as visualizações.

Tags de modelos - especialmente tags de inclusão - são úteis para renderizar áreas separadas da página que serão as mesmas em vários modelos.

Além disso, não se esqueça visualizações genéricas! Em 90% dos casos, você pode embrulhar object_list ou object_detail e salvar algum código.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top