0

我的代码中有以下index view代码views.py

   def index(request):  
        # Count all active polls for posting on the index page.
        all_active_polls = Poll.objects.filter(pub_date__lte=timezone.now(),
                                               is_active=True
                                              ).order_by('-pub_date')
        num_of_active_polls = len(all_active_polls)
        # Count all inactive polls for posting on the index page.
        all_inactive_polls = Poll.objects.filter(pub_date__lte=timezone.now(),
                                                 is_active=False
                                                ).order_by('-pub_date')
        num_of_inactive_polls = len(all_inactive_polls)
        # Make the list of the last 5 published polls.
        latest_poll_list = Poll.objects.annotate(num_choices=Count('choice')) \
               .filter(pub_date__lte=timezone.now(),
                       is_active=True,
                       num_choices__gte=2) \
               .order_by('-pub_date')[:5]
        return render(request, 'polls/index.html', {
            'latest_poll_list': latest_poll_list,
            'num_of_active_polls': num_of_active_polls,
            'num_of_inactive_polls': num_of_inactive_polls
            })

在索引页面上,我想列出我最近的 5 个(或更多,没关系)民意调查。之后我想要两个链接:View all active polls(number of polls)View all closed polls(number of polls). 所以我需要在index视图代码中计算它。但是,我不确定这是放置此代码的最佳位置(计算活动和非活动民意调查的数量)。

而且也许我会在其他一些视图中需要这个数字,所以我会将这段代码复制到这个视图中?我认为它伤害了DRY,而 Django 专注于坚持 DRY 原则。

那么我怎样才能重新组织这段代码,使其更符合逻辑并且不损害DRY原则呢?

4

2 回答 2

2

使用管理者使其更加 DRY,始终遵循原则——胖模型,瘦视图。这是执行此操作的一种方法:

模型.py

class ActiveManager(models.Manager):
    def get_query_set(self, active=True):
        return super(ActiveManager, self).\
            get_query_set().filter(pub_date__lte=timezone.now(), is_active=active)\
                           .order_by('-pub_date')

class InctiveManager(InctiveManager):
    def get_query_set(self):
        return super(InctiveManager, self).get_query_set(is_active=False)

class LatestManager(InctiveManager):
    def get_query_set(self):
        return super(LatestManager, self).get_query_set(is_active=True)\
                                         .filter(num_choices__gte=2)\
                                         .annotate(num_choices=Count('choice'))

class Poll(models.Model):
    ...

    objects = models.Manager()
    active = ActiveManager()
    inctive = InctiveManager()
    latest = LatestManager()

视图.py

all_active_polls = Poll.active.all()
num_of_active_polls = len(all_active_polls)

all_inactive_polls = Poll.inactive.all()
num_of_inactive_polls = len(all_inactive_polls)

latest_poll_list = Poll.latest.all()[:5]
于 2013-09-28T15:01:20.227 回答
1

我必须问,您不使用基于类的视图是否有原因?

您可以拥有一个带有最后轮询的ListViewn,您可以在 get_queryset 方法中定义该数字另一个具有不同查询集的 ListView,如果您愿意,该视图可以使用相同的模板或不同的模板。另一个 ListView 用于所有已结束的民意调查。

如果您有很多想要在所有视图中使用的自定义代码,只需编写一个所有其他基于类的视图都将继承的 mixin。

于 2013-09-28T12:17:29.240 回答