Skip to main content
 首页 » 编程设计

python之Django 编码风格 : Should I be using class decorators here

2024年08月30日25pander-it

我是整个 Django 的新手,因此,我决定从 ClassBased GenericViews 而不是旧的基于函数的 Generics 开始,这导致了一些绊脚石,因为缺乏文档。不管怎样,到目前为止我真的很喜欢 GenericViews 并且一直在用装饰器扩展它们。

我一直在做的简单例子

ideapad/urls.py

from ideapad.views import * 
 
urlpatterns = patterns('ideapad.views', 
        url(r'^$', IndexListView.as_view(), name='url_index'), 
        ) 

ideapad/views.py

from django.views.generic import ListView 
from ideapad.models import Idea 
from sauce.decorators import sort_queryset 
 
@sort_queryset('-date') 
class IndexListView(ListView): 
    model = Idea 
    template_name = 'ideapad/index.html' 
    context_object_name = 'ideas' 

sauce/decorators.py

def sort_queryset(default_sort): 
    """ 
    Decorator that sorts queryset according to GET data 
    Made to wrap GenericViews with get_queryset methods 
    """ 
    def decorator(cls): 
        fn=cls.get_queryset 
        def wrapper(self): 
            queryset = fn(self) 
            sortmethod = self.request.GET.get('sort', default_sort) 
            if hasattr(queryset, 'order_by'): 
                queryset = queryset.order_by(sortmethod) 
            return queryset 
        cls.get_queryset=wrapper 
        return cls 
    return decorator 

我的问题是,就整体可读性和可维护性而言,是否有“更好”或“更可接受”的方式来做到这一点?或者它只是一种编码风格偏好?

我问的原因是,虽然我认为这种方式更具可读性,但我希望有一天能通过这样做来赚钱,并且不想养成会激怒同事的奇怪编码习惯非常感谢任何关于编码风格的输入。谢谢。

请您参考如下方法:

这是执行此操作的正确方法(我已经编辑了您的代码):

ideapad/views.py

from django.views.generic import ListView 
from ideapad.models import Idea 
from sauce.decorators import SortQuerysetMixin 
 
class IndexListView(SortQuerysetMixin, ListView): 
    default_sort = '-date' 
    model = Idea 
    template_name = 'ideapad/index.html' 
    context_object_name = 'ideas' 

sauce/decorators.py

class SortQuerysetMixin(object): 
    def get_queryset(self): 
        queryset = super(SortQuerysetMixin, self).get_queryset() 
        sortmethod = self.request.GET.get('sort', self.default_sort) 
        if hasattr(queryset, 'order_by'): 
            queryset = queryset.order_by(sortmethod) 
        return queryset