Django - Советы, чтобы избежать повторения кода в представлениях - PullRequest
5 голосов
/ 20 марта 2010

Я перехожу из фона PHP в разработку Django с помощью python, в основном ради решения MVC (или MVT), который, на мой взгляд, имеет больше смысла, хотя в этом паттерне я начал замечать много повторный код в моих взглядах.

Например, когда я вошел в систему, у меня есть информация о пользователе, которую я хотел бы видеть на каждой странице, хотя при использовании render_to_response и в каждом представлении этого требуется, я должен получить информацию и передать ее в функцию render_to_response.

Мне интересно, какой самый эффективный способ сократить дублирующийся код, который по сути потребуется во всех представлениях в конкретном приложении.

Заранее спасибо.

Ответы [ 4 ]

5 голосов
/ 20 марта 2010

Существует два основных способа абстрагирования общего контента.

Контекстные процессоры лучше всего подходят для передачи битов данных, которые, как вы знаете, вам понадобятся при каждом просмотре.

Теги шаблонов - особенно теги включения - полезны для визуализации отдельных областей страницы, которые будут одинаковыми на нескольких шаблонах.

5 голосов
/ 20 марта 2010

Инкапсулируйте общий код в функцию и вызывайте его из разных представлений.Звучит банально, но это решение для 99% таких потребностей.

Для более конкретного ответа вам нужно будет показать более конкретный пример кода, который вы хотите запустить.

4 голосов
/ 21 марта 2010

Лично я большой поклонник декораторов, которые являются особенностью Python, которая не характерна для Django. Декораторы являются идеальным синтаксическим сахаром поверх функций более высокого порядка, и они особенно полезны для сокращения стандартного представления - вы можете быстро определить обобщенную функцию-обертку, в которую вы можете поместить повторяющийся код для легкого повторного использования и удобной. рефакторинг.

Вероятно, вам проще показать, чем объяснить, как они работают. Вот пример упрощенного просмотра:

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

... но затем скажите, что вы хотите, чтобы эти страницы требовали от пользователя входа в систему. Вы можете добавить код входа в систему следующим образом:

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

... который начинает заметно увеличиваться и повторяться даже для надуманного примера. Вы можете снова сделать свои функции тонкими с помощью декораторов, например:

из декоратора Импорт декоратора

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

Что происходит, если функция декоратора выполняется во время определения функции. 'F' в моем примере - это объект, представляющий функцию, к которой применяется декоратор, которой вы можете манипулировать бесконечным образом.

Для этого требуется библиотека декоратора , которая бесплатна для PyPI, как и многие хорошие кусочки Python, вы найдете.

Вам не нужна эта библиотека для написания функций декоратора, но это полезно, особенно в начале. Они могут сделать намного больше - любой вызывающий может быть декоратором; Вы можете украсить методы класса и перехватить переменную self; декораторы могут быть прикованы, например, так:

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

Я оставлю исследование того, что вы можете сделать с помощью такой простой функции высшего порядка для вас, если это понятие разожжет ваш аппетит. У меня есть еще много примеров для вас или любых других любопытных новых поклонников Python. Удачи.

3 голосов
/ 20 марта 2010

Кроме того, не забудьте о общих видах ! В 90% случаев вы можете обернуть object_list или object_detail и сохранить себе некоторый код.

...