Есть ли способ объединить функции просмотра похожих структур в одну? Django - PullRequest
0 голосов
/ 26 марта 2020

Я новичок в Django. Недавно я начал писать веб-приложение для управления запасами и понял, что когда я писал представления, их было много с похожей структурой. Например:

def invoices(request):
    """The page for displaying invoices."""
    invoice_list = Document.objects.filter(type_name__name='Invoice')
    page = request.GET.get('page', 1)
    paginator = Paginator(invoice_list, 10)

    try:
        invoices = paginator.page(page)
    except PageNotAnInteger:
        invoices = paginator.page(1)
    except EmptyPage:
        invoices = paginator.page(paginator.num_pages)

    context = {'invoices':invoices}
    return render(request, 'imsapp/invoices.html', context)

и этот:

def credit_notes(request):
    """The page for displaying credit notes."""
    credit_notes_list = Document.objects.filter(type_name__name='Credit Note')
    page = request.GET.get('page', 1)
    paginator = Paginator(credit_notes_list, 10)

    try:
        credit_notes = paginator.page(page)
    except PageNotAnInteger:
        credit_notes = paginator.page(1)
    except EmptyPage:
        credit_notes = paginator.page(paginator.num_pages)

    context = {'credit_notes':credit_notes}
    return render(request, 'imsapp/credit_notes.html', context)

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

Ответы [ 2 ]

0 голосов
/ 26 марта 2020

Представления - это просто Python функции - и поэтому они могут вызывать другие функции.

В приведенном выше коде похоже, что изменяются только имя объекта типа и шаблон.

Просто создайте новую функцию, которая принимает эти два в качестве параметров


def paged_view(request, type_name, template, name_in_context):
    """The page for displaying various items in a paginated way."""
    item_list = Document.objects.filter(type_name__name=time_name)
    page = request.GET.get('page', 1)
    paginator = Paginator(item_list, 10)

    try:
        items = paginator.page(page)
    except PageNotAnInteger:
        items = paginator.page(1)
    except EmptyPage:
        items = paginator.page(paginator.num_pages)

    context = {name_in_context:items}
    return render(request, template, context)

def invoices(request):
    """The page for displaying invoices."""
    return paged_view(requests, 'imsapp/invoices.html', 'Invoice', 'invoices')

def credit_notes(request):
    """The page for displaying credit notes."""
    return paged_view(requests, 'imsapp/credit_notes.html', 'Credit Note', 'credit_notes')
0 голосов
/ 26 марта 2020

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

def paginate(request, queryset):
    page_index = request.GET.get('page', 1)
    paginator = Paginator(queryset, 10)

    try:
        page = paginator.page(page_index)
    except PageNotAnInteger:
        page = paginator.page(1)
    except EmptyPage:
        page = paginator.page(paginator.num_pages)
    return page

def credit_notes(request):
    """The page for displaying credit notes."""
    credit_notes_list = Document.objects.filter(type_name__name='Credit Note')
    credit_notes = paginate(request, credit_notes_list)
    context = {'credit_notes':credit_notes}
    return render(request, 'imsapp/credit_notes.html', context)

Или вы можете использовать ListView

from django.views.generic.list import ListView
class CreditNoteListView(ListView):
    queryset = Document.objects.filter(type_name__name='Credit Note')
    paginate_by = 10
    template_name = 'imsapp/credit_notes.html'

В этом случае вам придется изменить шаблон, так как контекст шаблона будет немного отличаться.

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