Django:一个函数,两个基于类的视图

时间:2019-09-07 08:46:28

标签: python django

我目前正在努力为get_survey_state(self, context)找到更好的解决方案。 在两个CBV中都存在,我认为有比我更好的解决方案。你能建议我吗?

views.py

class SurveyExpectations(AdminPermissionRequiredMixin, TemplateView):
    template_name = 'admin/surveys/expectations.html'

    def get_survey_state(self, context):
        survey = self.request.event.surveys.active_pre_event().first()
        answers = Answer.objects.filter(question__survey=survey).exists()
        context['survey_is_active'] = survey
        context['answers_exist'] = answers

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        self.get_survey_state(context)
        context['questions_and_answers'] = self.request.event.surveys.get_results(
            settings.SURVEY_PRE_EVENT
        )
        return context

class SurveyFeedback(AdminPermissionRequiredMixin, TemplateView):
    template_name = 'admin/surveys/feedback.html'

    def get_net_promoter_score(self) -> float:
        [...]
        return netpromoterscore(scores)

    def get_average_age(self) -> int:
        [...]
        return int(answers['avg']) if answers['avg'] else None

    def get_survey_state(self, context):
        survey = self.request.event.surveys.active_post_event().first()
        answers = Answer.objects.filter(question__survey=survey).exists()
        context['survey_is_active'] = survey
        context['answers_exist'] = answers

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        self.get_survey_state(context)
        context['questions_and_answers'] = self.request.event.surveys.get_results(
            settings.SURVEY_POST_EVENT
        )
        context['netpromoterscore'] = self.get_net_promoter_score()
        context['average_age'] = self.get_average_age()
        return context

models.py

class SurveyQuerySet(models.QuerySet):
    def active_pre_event(self):
        return self.filter(is_active=True, template=settings.SURVEY_PRE_EVENT)

    def active_post_event(self):
        return self.filter(is_active=True, template=settings.SURVEY_POST_EVENT)

    def get_results(self, template):
        return (
            self.get(template=template)
            .questions.exclude(focus=QuestionFocus.EMAIL)
            .all()
            .prefetch_related('answers')
        )

class Survey(TimeStampedModel):
    id = models.UUIDField([...])
    is_active = models.BooleanField([...])
    template = models.CharField([...])

    objects = SurveyQuerySet.as_manager()

1 个答案:

答案 0 :(得分:1)

您可以使用类继承。创建一个基类(从TemplateView派生),在其中定义所有常用功能。

然后,您可以从基类派生更多视图,该基类将继承所有功能。

get_survey_state使用方法self.get_survey()允许在派生视图中使用不同的检索方法。

class BaseSurveyView(TemplateView):
    def get_survey_state(self, context):
        survey = self.get_survey()
        answers = Answer.objects.filter(question__survey=survey).exists()
        context['survey_is_active'] = survey
        context['answers_exist'] = answers

    def get_survey(self):
        raise NotImplementedError


class SurveyExpectations(AdminPermissionRequiredMixin, BaseSurveyView):
    template_name = 'admin/surveys/expectations.html'

    def get_survey(self):
        return self.request.event.surveys.active_pre_event().first()

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        self.get_survey_state(context)
        context['questions_and_answers'] = self.request.event.surveys.get_results(
            settings.SURVEY_PRE_EVENT
        )
        return context

class SurveyFeedback(AdminPermissionRequiredMixin, BaseSurveyView):
    template_name = 'admin/surveys/feedback.html'

    def get_survey(self):
        return self.request.event.surveys.active_post_event().first()

    def get_net_promoter_score(self) -> float:
        [...]
        return netpromoterscore(scores)

    def get_average_age(self) -> int:
        [...]
        return int(answers['avg']) if answers['avg'] else None

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        self.get_survey_state(context)
        context['questions_and_answers'] = self.request.event.surveys.get_results(
            settings.SURVEY_POST_EVENT
        )
        context['netpromoterscore'] = self.get_net_promoter_score()
        context['average_age'] = self.get_average_age()
        return context