Trying to DRY my Django code

Hi everybody.
I’m working on my first “real” project and it works ok. It is an activity project which builds a list of calender activities for exporting to an other system my job is using, and it expects a strict text format as input. But I’m starting to wonder if I am making it harder for myself than it has to be. This question is about best practice and maybe even finding som cases where my code breaks down.

This question is about using common code in multiple views.

I have many activities, so I built a model for limiting which daterange to use as the start and end dates and then getting all the activies in that period.

I use this as the beginning code in almost all my views, so I am thinking about extracting it to a GetCurrentActivities() or something like that, but before I do that, is there a more “professional” way. I am wondering about a decorator, a mixin or a middleware, but I don’t think I am able to understand fully what the recommended way is.
Example of the “common view code” her:

global_date_settings = GlobalDateSettings.objects.first()
    calendar_start_date = global_date_settings.start_date
    calendar_end_date = global_date_settings.end_date

    activities = Activity.objects.filter(
        Q(date__gte=calendar_start_date) & Q(date__lte=calendar_end_date)
    ).order_by("date")

My question is two-fold, but I split the debate into two separate posts - other one is here https://forum.djangoproject.com/t/using-a-django-model-to-store-constant/28892

This looks like a pretty standard use for either a custom queryset or custom manager.

See the docs at Managers | Django documentation | Django

I will look into that and report back here. Thank you!

Just read that post you linked to.
Just winging it I think I have do something like:

class CurrentActivitiesManager(models.Manager):
    def get_queryset(self):
       global_date_settings = GlobalDateSettings.objects.first()
       calendar_start_date = global_date_settings.start_date
       calendar_end_date = global_date_settings.end_date
       return super().get_queryset().filter(Q(date__gte=calendar_start_date),Q( date__lte=calendar_end_date))

then add it to my model like:

class Activities(models.Model):
    ...model fields here

    objects = models.Manager()  # The default manager.
    current_objects = CurrentActivitiesManager()  # The current activities manager.

Then just use it in the views like:
Activities.current_objects.all()
Right?

By the way. Should I have named the model Activity and not plural?

It looks right to me. Is it working for you?

Another option is to add this as a filter in an additional method in the Manager:

ActivityManager(models.Manager):
    def current(self):
        <the same code as in your get_queryset above, execpt the return line is:>
        return self.get_queryset().filter(date__gte=cal_start_dt, date__lte=cal_end_dt)

Then, if you set this in your model as:

objects = ActivityManager()

it would be used as:

Activity.objects.current()

Also note, your filter can be simplified by using the range test.

I would generally recommend that, yes.

I am not able to test it until tuesday. I will post here afterwards. :+1: