简体   繁体   中英

How to Convert DateTime to String in Django/DRF While Testing

I'm testing an endpoint which naturally returns a JSON containing the datetime as a string.

I compare the response content in test as such:

assert serializer_instance.data == {
    "created_at": str(model_instance.created_at),
    "updated_at": str(model_instance.updated_at),
}

created_at and updated_at are surely DateTimeField s. However, in this case, test fails saying:

E         Differing items:
E         {'created_at': '2020-06-24T12:42:03.578207+03:00'} != {'created_at': '2020-06-24 09:42:03.578207+00:00'}
E         {'updated_at': '2020-06-24T12:42:03.578231+03:00'} != {'updated_at': '2020-06-24 09:42:03.578231+00:00'}

So str uses a different formatting on datetimes. Sure, the test case can be passed successfully using strftime , but there should be an internal function that does it easily in either Django or Django Rest Framework and I'd like to learn it.

Thanks in advance.


Environment

  • Python 3.8.3
  • Django 2.2.12
  • Django Rest Framework 3.11.0

I've found a way. It uses parse_datetime method and, instead of converting DateTimeField fields on model instance with str , I thought it's better both stay as datetime .

from django.utils.dateparse import parse_datetime

data = serializer_instance.data
data["created_at"] = parse_datetime(data["created_at"])
# ... and the others ...

assert data == {
    # ... and the others ...
    "created_at": model_instance.created_at,
    # ... and the others ...
}

While this is okay, we mutate serializer_instance.data like this. I don't think it is going to be a problem in tests though.

For DRF I normally use

obj.ts_updated.astimezone(timezone(settings.TIME_ZONE)).isoformat()

This matches the DRF format.

I am a bit late to the party, But, better late than never!

I am using this method to assert datetime response in DRF

from rest_framework.fields import DateTimeField

drf_str_datetime = DateTimeField().to_representation
assert serializer_instance.data == {
    "created_at": drf_str_datetime(model_instance.created_at),
    "updated_at": drf_str_datetime(model_instance.updated_at),
}

you can use:

myDate.strftime('%m/%d/%Y')

or

'{:%m/%d/%Y}'.format(myDate)

For Django Rest Framework 3.11.0 you can use the following helper function to convert a Python datetime object into a string representation used by DRF:

from pytz import timezone as pytz_timezone

def convert_datetime_to_drf_str(date_time: datetime) -> str:
    return date_time.astimezone(pytz_timezone(settings.TIME_ZONE)).isoformat().replace("+00:00", "Z")

So, for your specific case it would be:

assert serializer_instance.data == {
    "created_at": convert_datetime_to_drf_str(model_instance.created_at),
    "updated_at": convert_datetime_to_drf_str(model_instance.updated_at),
}

or directly without the helper function:

from pytz import timezone as pytz_timezone

assert serializer_instance.data == {
    "created_at": model_instance.created_at.astimezone(pytz_timezone(settings.TIME_ZONE)).isoformat().replace("+00:00", "Z"),
    "updated_at": model_instance.updated_at.astimezone(pytz_timezone(settings.TIME_ZONE)).isoformat().replace("+00:00", "Z"),
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM