我试图通过create viewset方法向序列化程序发送多个数据。但是,当这样做时,我得到一个错误如下:
Error message
我在序列化器中使用了很多属性,但我还是会得到同样的错误。我发布的数据是这样的:
[
{
"weekday":"day",
"start_time":"time",
"end_time":"time"
},
{
"weekday":"day",
"start_time":"time",
"end_time":"time"
}
]
这是视图集和序列化器代码:
viewset.py
class SpecialistAvailabilityView(viewsets.ModelViewSet):
model = SpecialistAvailability
permission_classes = [IsAuthenticated, IsSpecialist]
def get_serializer_class(self):
saving_actions = ["create", "update", "partial_update"]
if self.action in saving_actions:
return WeekDayTimeSerializer
return SpecialistAvailabilitySerializer
def get_queryset(self):
queryset = SpecialistAvailability.objects.filter(
specialist__user=self.request.user
).order_by('-start_time__week_day')
return queryset
def translate_availability(self, data):
pass
def create(self, request, *args, **kwargs):
serializer = WeekDayTimeSerializer(data=request.data, many=isinstance(request.data, list))
print(serializer.initial_data)
print(serializer.is_valid())
if serializer.is_valid():
self.translate_availability(serializer.validated_data)
return super().create(request, *args, **kwargs)
serializer.py
import pytz
from datetime import datetime
from rest_framework import serializers
from apps.specialist.models.specialist_availability import SpecialistAvailability
from apps.specialist.utils import WEEKDAYS
class WeekDayTimeSerializer(serializers.Serializer):
weekday = serializers.ChoiceField(choices=WEEKDAYS, required=True)
start_time = serializers.TimeField()
end_time = serializers.TimeField()
# TODO ADD TIME AND WEEKDAY CHECKING
# START TIME MUST BE LESS THAN END TIME
# JUST ONE DAY MUST BE SENDED IF MANY
def validate(self, attrs):
self.validate_start_time(attrs['start_time'])
self.validate_start_time(attrs['end_time'])
self.validate_end_time
return super().validate(attrs)
def validate_start_time(self, start_time):
try:
datetime.strptime(start_time, "%H:%M")
except:
raise serializers.ValidationError("Wrong time format")
return start_time
def validate_end_time(self, end_time):
try:
datetime.strptime(end_time, "%H:%M")
except:
raise serializers.ValidationError("Wrong time format")
return end_time
class SpecialistAvailabilitySerializer(serializers.ModelSerializer):
class Meta:
model = SpecialistAvailability
fields = ['id', 'specialist', 'start_time', 'end_time']
def to_representation(self, instance):
localized_start_time = self.set_time_to_local(instance.start_time)
localized_end_time = self.set_time_to_local(instance.end_time)
data = {
'availability': {
'id': instance.id,
'start_day': localized_start_time.strftime('%A'),
'start_day_code': localized_start_time.isoweekday(),
'start_time': localized_start_time.time(),
'end_day': localized_end_time.strftime('%A'),
'end_day_code': localized_end_time.isoweekday(),
'end_time': localized_end_time.time()
}
}
return data
def validate(self, attrs):
instance = getattr(self, 'instance', None)
if instance:
attrs['id'] = instance.id
specialist_availability = self.Meta.model(**attrs)
specialist_availability.clean()
super().validate(attrs)
attrs['start_time'] = self.set_time_to_utc(attrs['start_time'])
attrs['end_time'] = self.set_time_to_utc(attrs['end_time'])
return attrs
def set_time_to_local(self, time):
request_user = self.context['request'].user
user_tz = request_user.timezone
if user_tz == pytz.utc:
return time
unlocalized_time = time.replace(tzinfo=None)
utc_time = pytz.utc.localize(unlocalized_time)
local_time = utc_time.astimezone(user_tz)
return local_time
def set_time_to_utc(self, time):
request_user = self.context['request'].user
user_tz = request_user.timezone
if user_tz == pytz.utc:
return time
unlocalized_time = time.replace(tzinfo=None)
local_time = user_tz.localize(unlocalized_time)
utc_time = local_time.astimezone(pytz.utc)
return utc_time
1条答案
按热度按时间v440hwme1#
您已经在
SpecialistAvailabilityView,
中覆盖了viewsets.ModelViewSet
的方法create()
,但毕竟您只是调用父方法super().create(request, *args, **kwargs)
。因此,实际上,你自己的代码在方法create()
中并不适用。同时,父
create()
方法总是在序列化器调用中使用many=False
。所以,你只需要替换行
由