I have django model:
from django.db import models
from timezone_field import TimeZoneField
class Client(models.Model):
time_zone = TimeZoneField(choices_display='WITH_GMT_OFFSET')
And APIView for this model:
class ClientAPIView(APIView):
def get(self, request: Request, pk: int, format=None) -> Response:
client = get_object_or_404(Client, pk=pk)
client_serializer = ClientListSerializer(client)
return Response(client_serializer.data)
I get an error from GET request: TypeError: Object of type ZoneInfo is not JSON serializable
Serializer code:
class ClientListSerializer(serializers.ModelSerializer):
class Meta:
model = Client
fields = ('id', 'time_zone')
How fix code of Model, Serializer or View (I don't know what exactly) so that instead of ZoneInfo there is just a string.
UPDATE: if change serializer:
class ClientListSerializer(serializers.ModelSerializer):
time_zone = serializers.CharField(max_length=256)
GET request will be work, but POST request give me error, if send invalid string for time zone. For example {"time_zone": "invalid string"}
Result: django.core.exceptions.ValidationError: ["Invalid timezone 'invalid string'"]
My POST method code:
def post(self, request: Request, format=None) -> Response:
client_serializer = ClientSerializer(data=request.data)
if not client_serializer.is_valid():
return Response(client_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
client_serializer.save()
return Response('client was created successfully', status=status.HTTP_201_CREATED)
SOLVED
Maybe this is not the best solution, but now requests work correctly after modify serializer
:
import pytz
from rest_framework import serializers
class ClientSerializer(serializers.ModelSerializer):
time_zone = serializers.ChoiceField(choices=pytz.all_timezones)
class Meta:
model = Client
fields = ('id', 'time_zone')
If you know better solution, share with me
Django 4.0+
Django 4.0 makes zoneinfo
the default implementation. Support for pytz
is now deprecated and will be removed in Django 5.0.
from zoneinfo import available_timezones
from rest_framework import serializers
class ClientSerializer(serializers.ModelSerializer):
time_zone = serializers.ChoiceField(choices=available_timezones())
class Meta:
model = Client
fields = ['id', 'time_zone', ]