title: Django ORM DateTimeField ExpressionWrapper QuerySet annotation
body: <p>According to the Django documentation here: <a href="https://docs.djangoproject.com/en/2.1/ref/models/expressions/#using-f-with-annotations" rel="nofollow noreferrer">https://docs.djangoproject.com/en/2.1/ref/models/expressions/#using-f-with-annotations</a></p>
  
  <p>I can do date calculations using ExpressionWrapper. I tried to use it like this:</p>
  
  <pre><code>    sprints = Sprint.objects.annotate(
          duration=models.Case(
              models.When(
                  Q(started__isnull=False) &amp;
                  Q(done__isnull=False),
                  then=models.Value(
                      models.ExpressionWrapper(
                          (models.F('done') - models.F('started')),
                          output_field=models.DateTimeField()
                      ))
              ),
              models.When(
                  Q(started__isnull=False) &amp;
                  Q(done__isnull=True),
                  then=models.Value(
                      models.ExpressionWrapper(
                          (Now() - models.F('started')),
                          output_field=models.DateTimeField(),
                      ))
              ),
              output_field=models.DateTimeField()
          )).values_list('name',
                         'planned',
                         'started',
                         'done',
                         'duration')
  </code></pre>
  
  <p>But I get an error from pytz trying to do auto-localisation on the ExpressionWrapper:</p>
  
  <pre><code>Traceback (most recent call last):
    File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
      response = get_response(request)
    File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
      response = self.process_exception_by_middleware(e, request)
    File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
      response = wrapped_callback(request, *callback_args, **callback_kwargs)
    File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
      return view_func(*args, **kwargs)
    File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/rest_framework/viewsets.py", line 103, in view
      return self.dispatch(request, *args, **kwargs)
    File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/rest_framework/views.py", line 483, in dispatch
      response = self.handle_exception(exc)
    File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/rest_framework/views.py", line 443, in handle_exception
      self.raise_uncaught_exception(exc)
    File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/rest_framework/views.py", line 480, in dispatch
      response = handler(request, *args, **kwargs)
    File "/home/phirt/src/core3/src/backend/portal/views/api/transformation.py", line 766, in get_sprint_data_csv
      for sprint in sprints:
    File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/db/models/query.py", line 272, in __iter__
      self._fetch_all()
    File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/db/models/query.py", line 1179, in _fetch_all
      self._result_cache = list(self._iterable_class(self))
    File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1011, in apply_converters
      value = converter(value, expression, connection)
    File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/db/backends/mysql/operations.py", line 247, in convert_datetimefield_value
      value = timezone.make_aware(value, self.connection.timezone)
    File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/utils/timezone.py", line 269, in make_aware
      return timezone.localize(value, is_dst=is_dst)
    File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/pytz/__init__.py", line 226, in localize
      if dt.tzinfo is not None:
  AttributeError: 'str' object has no attribute 'tzinfo'
  </code></pre>
  
  <p>And indeed the <code>dt</code> parameter passed to <code>localize</code> in pytz is a string, and it's exactly my ExpressionWrapper expression: <code>ExpressionWrapper(F(done) - F(started))</code></p>
  
  <p>How can I make this work?</p>
  
  <p>Edit: Here is the sprint model:</p>
  
  <pre><code>class Sprint(BaseModel):
      name = models.CharField(max_length=100)
      planned = models.DateTimeField(null=True, blank=True)
      started = models.DateTimeField(null=True, blank=True)
      done = models.DateTimeField(null=True, blank=True)
      state = models.CharField(max_length=20, verbose_name='State')
      start_planned = models.DateTimeField(blank=True, null=True,
                                           verbose_name='Start Planned')
      start_latest = models.DateTimeField(blank=True, null=True,
                                          verbose_name='Start Latest')
      enforce_start = models.BooleanField(default=False,
                                          verbose_name='Enforce Start')
  
      class Meta:
          ordering = ["name"]
          verbose_name = "Sprint"
  
      def __str__(self):
          return f'&lt;Sprint name="{self.name}"&gt;'
  </code></pre>