#34962: Support for overriding result of model field values
-------------------------------------+-------------------------------------
               Reporter:             |          Owner:  nobody
  piraka9011                         |
                   Type:  New        |         Status:  new
  feature                            |
              Component:  Database   |        Version:  4.2
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:  QuerySet.extra
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 We have many models with timestamp fields (ex. `created_at`, `updated_at`,
 etc.) that store `DateTimeField`s.
 We use Django as a REST API for web and mobile clients written using
 JavaScript where time is stored as milliseconds since the UNIX epoch (i.e.
 `Date.now()`).

 To minimize the amount of processing we do client side, we convert
 `DateTimeField`s to milliseconds using a Django Rest Framework (DRF)
 serializer that looks like this:

 {{{
 class TimestampDateTimeField(serializers.DateTimeField):
     """Convert Python datetime to/from Unix timestamp in milliseconds.
     For use with JavaScript's Date objects which use ms since epoch, not
 seconds.
     """

     def to_representation(self, value):
         return round(value.timestamp() * 1000)

     def to_internal_value(self, value):
         try:
             result = datetime.fromtimestamp(value / 1000,
 timezone.get_default_timezone())
             return super(TimestampDateTimeField,
 self).to_internal_value(result)
         except TypeError:
             raise serializers.ValidationError("Datetime must be a number,
 not a string")
 }}}

 Ideally, we could instead do this data manipulation at the database layer
 using the `Extract` function **but** with the same behavior as the
 serializer where we can override the original name of the field.

 Example:

 {{{
 # This will currently throw an error
 # ValueError: The annotation 'updated_at' conflicts with a field on the
 model.
 m = MyModel.objects.filter(user=user).annotate(
   updated_at=Extract("updated_at", "epoch") * 1000
 )
 }}}



 The way we can do this instead is using the `extra()` method from the
 `QuerySet` API to generate a query that would look like:

 {{{
 SELECT (EXTRACT(EPOCH FROM app_mymodel.updated_at) * 1000) AS updated_at
 FROM app_mymodel
 WHERE app_mymodel.user_id = 42
 LIMIT 1;
 }}}

 I did my best to look online and in the docs for potential
 solutions/workarounds, but all point back to using the `extra()`. Is there
 a way to do this w/o using `extra()`?

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34962>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018bb462c080-3800d54d-4e94-4755-9472-22de32148916-000000%40eu-central-1.amazonses.com.

Reply via email to