作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是一名初学者,我一直在使用 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})
分页逻辑也在其他一些函数中重复。
我应该把重复的代码放在哪里以及如何决定是否应该组织代码?
最佳答案
您可以将其封装在另一个函数中(例如在名为 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 <b>get_page_entries</b>
def entry_list(request):
entry_list = Entry.objects.all()
entries= <b>get_page_entries(</b>entry_list, request.GET.get('page', 1)<b>)</b>
return render(request, 'blog/entry_list.html', {'entries': entries})
您可以提供可选的第三个参数,其中包含每页的元素数量。如果未提供,则默认为 10。
或者我们也可以封装 request.GET.get(..)
逻辑,例如:
# in app/utils.py
def get_page_entries(entry_list, <b>querydict</b>, per_page=10, key='page', default_page=1):
<b>page = querydict.get(key, default_page)</b>
paginator = Paginator(entry_list, per_page)
try:
return paginator.page(page)
except PageNotAnInteger:
return paginator.page(<b>default_page</b>)
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(), <b>request.GET</b>)
})
但是,您不需要需要使用基于函数的 View 。 ListView
class [Django-doc] 涵盖了此用例。 :
class EntryListView(ListView):
model = Entry
template_name = 'blog/entry_list.html'
context_object_name = 'entries'
<b>paginate_by = 10</b>
然后在urls.py
中,使用EntryListView.as_view()
而不是函数,所以:
# app/urls.py
from django.urls import path
from app.views import EntryListView
urlpatterns = [
path('entries', <b>EntryListView.as_view()</b>, name='entry-list'),
]
请注意,我们减少了代码行数,这也是一种更具声明性的开发方式:我们不需要指定我们想要做什么,而是指定我们想要做什么。它是如何完成的更多取决于 Django 的 ListView
实现。此外,通过提供设置作为类的属性,我们可以轻松开发更多考虑这些参数的工具。
关于python - Django ;使 View 变薄的技巧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51896025/
我是一名优秀的程序员,十分优秀!