在Django视图中组织代码

时间:2013-09-28 12:01:51

标签: python django django-views dry

我在index view的{​​{1}}中有以下代码:

views.py

在索引页面上,我想要列出我最近5次(或更多,无关紧要)的民意调查。 之后我想要两个链接: 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 }) View all active polls(number of polls)。所以我需要在View all closed polls(number of polls)视图代码中计算它。 但是,我不确定它是放置此代码的最佳位置(计算活动和非活动轮询的数量)。

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

那么我该如何重新组织这段代码以使其更符合逻辑并且不会损害 DRY 原则呢?

2 个答案:

答案 0 :(得分:2)

使用managers使其更干燥,始终遵循原则 - 胖模型,瘦视图。 这是一种方法:

models.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()

views.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]

答案 1 :(得分:1)

我必须问,你有没有理由不使用class based views

你可以让一个ListView进行最后一次民意调查n,你可以在get_queryset方法中定义这个数字 具有不同查询集和该视图的另一个ListView可以使用相同的模板,如果您愿意或不同的。 所有已结束民意调查的另一个ListView。

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