Django;缩小视图的提示

时间:2018-08-17 13:00:16

标签: python django

我是一个初学者,我一直在使用Django进行项目开发。 我想知道是否有避免重复相同代码的好方法。 另外,如果某些功能中有类似的逻辑,该如何确定该逻辑是否组织。

例如

def entry_list(request):
    entry_list = Entry.objects.all()

    #this part is repeated
    page = request.GET.get('page', 1)


    paginator = Paginator(entry_list, 10)

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

    return render(request, 'blog/entry_list.html', {'entries': entries})

在其他一些功能中也重复了分页逻辑。

我应该在哪里放置重复的代码,如何确定是否应该组织代码?

2 个答案:

答案 0 :(得分:3)

使用基于基于功能的视图

您可以将其封装到另一个函数中(例如,在名为utils.py的文件中构造该函数):

# in app/utils.py

def get_page_entries(entry_list, page, per_page=10):
    paginator = Paginator(entry_list, per_page)
    try:
        return paginator.page(page)
    except PageNotAnInteger:
        return paginator.page(1)
    except EmptyPage:
        return paginator.page(paginator.num_pages)

然后您可以像这样使用它:

# app/views.py

from app.utils import get_page_entries

def entry_list(request):
    entry_list = Entry.objects.all()

    entries= get_page_entries(entry_list, request.GET.get('page', 1))

    return render(request, 'blog/entry_list.html', {'entries': entries})

您可以提供第三个可选参数,其中包含每页元素的数量。如果未提供,则默认为10。

或者我们也可以封装request.GET.get(..)逻辑,例如:

# in app/utils.py

def get_page_entries(entry_list, querydict, per_page=10, key='page', default_page=1):
    page = querydict.get(key, default_page)
    paginator = Paginator(entry_list, per_page)
    try:
        return paginator.page(page)
    except PageNotAnInteger:
        return paginator.page(default_page)
    except EmptyPage:
        return paginator.page(paginator.num_pages)

,因此调用:

# app/views.py

from app.utils import get_page_entries

def entry_list(request):
    return render(request, 'blog/entry_list.html', {
        'entries': get_page_entries(Entry.objects.all(), request.GET)
    })

使用基于基于类的视图

不需要使用基于功能的视图。 ListView class [Django-doc]涵盖了该用例:

class EntryListView(ListView):
    model = Entry
    template_name = 'blog/entry_list.html'
    context_object_name = 'entries'
    paginate_by = 10

,然后在urls.py中,使用EntryListView.as_view()代替函数,因此:

# app/urls.py

from django.urls import path

from app.views import EntryListView

urlpatterns = [
    path('entries', EntryListView.as_view(), name='entry-list'),
]

请注意,我们只是减少了代码行的数量,这也是一种更具声明性的开发方式:我们无需指定操作方式,而是要做指定我们要做的 。如何完成取决于Django对ListView的实现。此外,通过将设置提供为类的属性,我们可以轻松开发出更多考虑这些参数的工具。

答案 1 :(得分:0)

我在几件事上问了自己同样的问题,

  • 功能,我在视图中可能会多次使用
  • 消息:我会在视图中使用很多次,还会进行测试(以测试我的应用程序的行为),
  • 可以在许多模型或视图中使用的
  • 例外
  • 定义Charfields时,
  • 选择,该值只能是特定值,
  • 可以在许多模板中使用的
  • context 值,

例如,这是我的工作方式:

  • 功能:就像Willem所说的那样,一个utils.py文件,
  • 消息:我有一个customMessages.py文件,用于定义简单消息(例如:SUCCESS_M_CREATE_OBJECT=_("You created this object successfully."),然后通过调用customMessages.SUCCESS_M_CREATE_OBJECT使用在我的模型,测试或视图中)或更复杂的变量字段(例如,由函数定义并在我的测试中用lambda调用)
  • context :通过在我的context_processors.py中定义专用函数并返回上下文变量字典,将它们注册到我的settings.py中,然后我想在其中调用任何函数就可以了我的模板,

嗯,总有一种方法可以使您在Python和Django中所做的任何事情都不再重复,而您在开发中的任何时候都可以问自己这些问题是正确的,因为您自己的未来会为此感谢您! / p>