基本上,我有一个相当大的Django项目。它是一个私人门户网站,允许用户管理各种与电话相关的任务。
门户网站的几个页面向用户提供了Model对象列表,并在HTML表格中列出了所有属性(以便用户可以直观地查看这些项目的列表)。
我遇到的问题是:我找不到Django-ish或pythonic方式来处理按字段名称对这些Model对象进行排序。作为我正在谈论的一个例子,这是我的一个观点,其中列出了所有Partyline
模型对象:
def list_partylines(request):
"""
List all `Partyline`s that we own.
"""
# Figure out which sort term to use.
sort_field = request.REQUEST.get('sortby', 'did').strip()
if sort_field.startswith('-'):
search = sort_field[1:]
sort_toggle = ''
else:
search = sort_field
sort_toggle = '-'
# Check to see if the sort term is valid.
if not (search in Partyline._meta.get_all_field_names()):
sort_field = 'did'
if is_user_type(request.user, ['admin']):
partylines = Partyline.objects.all().order_by(sort_field)
else:
partylines = get_my_partylines(request.user, sort_field)
variables = RequestContext(request, {
'partylines': partylines,
'sort_toggle': sort_toggle
})
return render_to_response('portal/partylines/list.html', variables)
排序代码基本上允许用户指定/ url /?sortby = model_field_name参数,当用户点击页面上显示的HTML表名时,该参数将返回对象的有序列表。
由于我在各种应用程序中都有各种视图,它们都显示了Model对象的列表,并且需要排序,我想知道是否有一种通用的方法来进行这种排序,以便我不必这样做?
如果这个问题有点不清楚,我很抱歉,我很难找到正确的方法来表达这个问题。
感谢。
答案 0 :(得分:2)
我这样做的方式是通过自定义QuerySet。在您的模型中,您可以定义类QuerySet
并在那里添加排序。为了维护模型对象中的所有逻辑,我还将get_my_partylines
的内容移动到QuerySet中。
## This class is used to replicate QuerySet methods into a manager.
## This way: Partyline.objects.for_user(foo) works the same as
## Partyline.objects.filter(date=today).for_user(foo)
class CustomQuerySetManager(models.Manager):
def get_query_set(self):
return self.model.QuerySet(self.model)
def __getattr__(self, attr, *args):
try:
return getattr(self.__class__, attr, *args)
except AttributeError:
return getattr(self.get_query_set(), attr, *args)
class Partyline(models.Model):
## Define fields, blah blah.
objects = CustomQuerySetManager()
class QuerySet(QuerySet):
def sort_for_request(self, request):
sort_field = request.REQUEST.get('sortby', 'did').strip()
reverse_order = False
if sort_field.startswith('-'):
search = sort_field[1:]
else:
search = sort_field
reverse_order = True
# Check to see if the sort term is valid.
if not (search in Partyline._meta.get_all_field_names()):
sort_field = 'did'
partylines = self.all().order_by(sort_field)
if reverse_order:
partylines.reverse()
return partylines
def for_user(self, user):
if is_user_type(request.user, ['admin']):
return self.all()
else:
## Code from get_my_partylines goes here.
return self.all() ## Temporary.
<强> views.py 强>:
def list_partylines(request):
"""
List all `Partyline`s that we own.
"""
partylines = Partylines.objects.for_user(request.user).sort_for_request(request)
答案 1 :(得分:0)
有一个很好的例子,说明如何在django.contrib.admin.views.main.ChangeList
中以通用方式完成此操作,尽管除了排序之外,您可以浏览它的代码以获取一些提示和想法。您可能还希望特别查看django.contrib.admin.options.ModelAdmin
changelist
方法以获取更多背景信息。