代码之家  ›  专栏  ›  技术社区  ›  rdegges

Django有自动排序模型字段的方法吗?

  •  1
  • rdegges  · 技术社区  · 14 年前

    所以基本上,我有一个相当大的Django项目。它是一个私有的门户网站,允许用户管理各种与电话相关的任务。

    我遇到的问题是:我找不到Django ish或pythonic方法来处理按字段名排序这些模型对象。作为我所说的例子,这里是我的一个观点,列出了所有 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\u field\u name参数,每当用户单击页面上显示的HTML表名时,该参数将返回对象的排序列表。

    很抱歉,如果这个问题有点不清楚,我正在努力找到正确的方式来表达这个问题。

    谢谢。

    2 回复  |  直到 14 年前
        1
  •  2
  •   Jack M.    14 年前

    我认为这样做的方式是通过一个定制的查询集。在模型中,可以定义类 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.
    

    视图.py :

    def list_partylines(request):
        """
        List all `Partyline`s that we own.
        """
        partylines = Partylines.objects.for_user(request.user).sort_for_request(request)
    
        2
  •  0
  •   Vasil    14 年前

    有一个很好的例子,说明了如何在 django.contrib.admin.views.main.ChangeList django.contrib.admin.options.ModelAdmin 这个 changelist 方法来获取更多上下文。