Helana Brock
Helana Brock

Reputation: 55

How can I condense all these similar views into one?

All of these views are very similar, and I would like to condense them into one view.

class SummerIntents(TemplateView):

    template_name = 'admin/hr/intent_forms/summer_intents.html'

    @user_is_staff
    def dispatch(self, request, *args, **kwargs):
        return super(SummerIntents, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(SummerIntents, self).get_context_data(**kwargs)

        # These functions are found in util.py
        update_date = get_update_date()
        active_users = get_active_users(self)

        context['summer_info'] = SummerInfo.objects.filter(employee__in=active_users, date_modified__gte=update_date.date, active=True).order_by('position','employee__last_name')
        return context

    def post(self, request, *args, **kwargs):
        context = super(SummerIntents, self).get_context_data(**kwargs)
        file_name = "summer_intent_forms"

        update_date = get_update_date()
        active_users = get_active_users(self)
        info = SummerInfo.objects.filter(employee__in=active_users, date_modified__gte=update_date.date, active=True).order_by('position','employee__last_name')
        student_intents = get_student_intents(active_users, update_date, 'summer', info)

        return intents_to_csv(student_intents, file_name)


class WinterIntents(TemplateView):

    template_name = 'admin/hr/intent_forms/winter_intents.html'

    @user_is_staff
    def dispatch(self, request, *args, **kwargs):
        return super(WinterIntents, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(WinterIntents, self).get_context_data(**kwargs)

        # These functions are found in util.py
        update_date = get_update_date()
        active_users = get_active_users(self)

        context['winter_info'] = WinterInfo.objects.filter(employee__in=active_users, date_modified__gte=update_date.date, active=True).order_by('position','employee__last_name')
        return context

    def post(self, request, *args, **kwargs):
        context = super(WinterIntents, self).get_context_data(**kwargs)
        file_name = "winter_intent_forms"

        update_date = get_update_date()
        active_users = get_active_users(self)
        info = WinterInfo.objects.filter(employee__in=active_users, date_modified__gte=update_date.date, active=True).order_by('position','employee__last_name')
        student_intents = get_student_intents(active_users, update_date, 'winter', info)

        return intents_to_csv(student_intents, file_name)


class FallIntents(TemplateView):

    template_name = 'admin/hr/intent_forms/fall_intents.html'

    @user_is_staff
    def dispatch(self, request, *args, **kwargs):
        return super(FallIntents, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(FallIntents, self).get_context_data(**kwargs)

        # These functions are found in util.py
        update_date = get_update_date()
        active_users = get_active_users(self)

        context['fall_info'] = FallInfo.objects.filter(employee__in=active_users, date_modified__gte=update_date.date, active=True).order_by('position','employee__last_name')
        return context

    def post(self, request, *args, **kwargs):
        context = super(FallIntents, self).get_context_data(**kwargs)
        file_name = "fall_intent_forms"

        update_date = get_update_date()
        active_users = get_active_users(self)
        info = FallInfo.objects.filter(employee__in=active_users, date_modified__gte=update_date.date, active=True).order_by('position','employee__last_name')
        student_intents = get_student_intents(active_users, update_date, 'fall')

        return intents_to_csv(student_intents, file_name, info)

I am open to one main view they all inherit from, but would that mean I have to pass some variables through context? Such as update_date and active_users? I would prefer not to add another method on top of these ones, especially since they are already so short and a main view to inherit from wouldn't do too much good. Secondly, they each have a post method that saves the templates as CSV file when a button is clicked, and I don't know how to condense that so that all the buttons still function properly. Finally, they all have different templates, would I have to condense them into one file as well? That's what I'm hoping to do eventually.

Upvotes: 0

Views: 126

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599856

I'm not sure what you mean by having to "pass some variables through context", but inheritance is definitely the way to go here.

Note even within each view you have some duplication, such as getting the Info objects which can be abstracted out into a separate method. Note also that you can avoid defining dispatch just to decorate it if instead you add the django.contrib.auth.mixins.UserPassesTestMixin and define test_func.

class Intents(UserPassesTestMixin, TemplateView):

    def test_func(self):
        return self.request.user.is_staff

    def get_template_names(self):
         return 'admin/hr/intent_forms/{}_intents.html'.format(self.season_name)

    def get_info_items(self):
        update_date = get_update_date()
        active_users = get_active_users(self)
        return self.info_model.objects.filter(employee__in=active_users, date_modified__gte=update_date.date, active=True).order_by('position','employee__last_name')

    def get_context_data(self, **kwargs):
        kwargs['{}_info'.format(self.season_name)] = self.get_info_items()
        return super().get_context_data(**kwargs)

    def post(self, request, *args, **kwargs):
        file_name = "{}_intent_forms".format(self.season_name)
        info = self.get_info_items()
        student_intents = get_student_intents(active_users, update_date, self.season_name, info)

        return intents_to_csv(student_intents, file_name)

class SummerIntents(Intents):
    season_name = 'summer'
    info_model = SummerInfo

class WinterIntents(Intents):
    season_name = 'winter'
    info_model = WinterInfo

class FallIntents(Intents):
    season_name = 'fall'
    info_model = FallInfo

(Also, it's a bit odd to have get_active_users as a utility method that accepts the view class as a parameter. Are you sure that shouldn't be a method on the view?)

Upvotes: 2

Related Questions