title: Is it bad practice to return a tuple from a Django Manager method rather than a queryset?
body: <p>I have some complex business logic that I have placed in a custom ModelManager. The manager method returns a tuple of values rather than a queryset. Is this considered bad practice? if so, what is the recommended approach. I do not want the logic in the View, and Django has no Service tier. Plus, my logic needs to potentially perform multiple queries.</p>
  
  <p>The logic needs to select an Event closest to the current time, plus 3 events either side. When placed in the template, it is helpful to know the closest event as this is the event initially displayed in a full-screen slider.</p>
  
  <p>The current call is as follows:</p>
  
  <pre><code>closest_event, previous_events, next_events = Event.objects.closest()
  </code></pre>
  
  <p>The logic does currently work fine. I am about to convert my app. to render the Event data as JSON in the template so that I can bootstrap a backbone.js View on page load. I plan to use TastyPie to render a Resource server-side into the template. Before I refactor my code, it would be good to know my current approach is not considered bad practice.</p>
  
  <p>This is how my app. currently works:</p>
  
  <p>views.py</p>
  
  <pre><code>class ClosestEventsListView(TemplateView):
      template_name = 'events/event_list.html'
  
      def get(self, request, *args, **kwargs):
          context = self.get_context_data(**kwargs)
          closest_event, previous_events, next_events = Event.objects.closest()
  
          context['closest_event'] = closest_event
          context['previous_events'] = previous_events
          context['next_events'] = next_events
          return self.render_to_response(context)
  </code></pre>
  
  <p>models.py</p>
  
  <pre><code>from datetime import timedelta
  from django.db import models
  from django.utils import timezone
  
  from model_utils.models import TimeStampedModel
  
  class ClosestEventsManager(models.Manager):
      def closest(self, **kwargs):
          """
          We are looking for the closest event to now plus the 3 events either side.
          First select by date range until we have a count of 7 or greater
          Initial range is 1 day eithee side, then widening by another day, if required
          Then compare delta for each event data and determine the closest
          Return closest event plus events either side
          """
          now = timezone.now()
          range_in_days = 1
          size = 0
  
          while size &lt; 7:
              start_time = now + timedelta(days=-range_in_days)
              end_time = now + timedelta(days=range_in_days)
              events = self.filter(date__gte=start_time, date__lte=end_time, **kwargs).select_related()
              size = events.count()
              range_in_days += 1
  
          previous_delta = None
          closest_event = None
          previous_events = None
          next_events = None
          position = 0
  
          for event in events:
              delta = (event.date - now).total_seconds()
              delta = delta * -1 if delta &lt; 0 else delta
              if previous_delta and previous_delta &lt;= delta:
                  # we have found the closest event. Now, based on
                  # position get events either size
                  next_events = events[:position-1]
                  previous_events = events[position:]
                  break
  
              previous_delta = delta
              closest_event = event
              position += 1
  
          return closest_event, previous_events, next_events
  
  
  class Event(TimeStampedModel):
  
      class Meta:
          ordering = ['-date']
  
      topic = models.ForeignKey(Topic)
      event_type = models.ForeignKey(EventType)
      title = models.CharField(max_length=100)
      slug = models.SlugField()
      date = models.DateTimeField(db_index=True)
      end_time = models.TimeField()
      location = models.ForeignKey(Location)
      twitter_hashtag = models.CharField(null=True, blank=True, max_length=100)
      web_link = models.URLField(null=True, blank=True)
  
      objects = ClosestEventsManager()
  
      def __unicode__(self):
          return self.title
  </code></pre>