Django выдает пользовательскую ошибку при недопустимых параметрах API
Я пишу конечную точку API, которая запрашивает Event
в заданном временном окне.
Модель Event
имеет время начала и окончания, а запрос принимает время начала поиска и время окончания поиска. Возвращается любое Событие, которое пересекается между этими двумя окнами. Это работает хорошо.
Однако, если пользователь запрашивает поиск, используя search_time_start
, который находится после search_time_end
, он не выдает никаких результатов (очевидно), без указания причины.
Вместо этого я хотел бы вернуть сообщение об ошибке, указывающее на то, что не так.
У меня есть приблизительное представление о том, как это сделать, но не о том, как подключить это к моему существующему коду.
Модель
class Event(models.Model):
name = model.CharField(max_length=64)
start_time = models.DateTimeField(null=False)
end_time = models.DateTimeField(null=False)
Сериализатор
class EventSerializer(serializers.ModelSerializer):
start_time = serializers.DateTimeField()
end_time = serializers.DateTimeField()
class Meta:
model = Event
fields = ("start_time", "end_time")
Фильтр и вид
class EventFilterSet(GeoFilterSet):
search_time_start = DateTimeFilter(
field_name="end_time",
lookup_expr="gte",
help_text=(
"The time for the start of the search. Limits events to those that end after the start time."
),
)
search_time_end = DateTimeFilter(
field_name="start_time",
lookup_expr="lte",
help_text=(
"The time for the end of the search. Limits events to those that start before the end time."
),
)
class Meta:
model = Event
fields = ["search_time_start", "search_time_end"]
class BaseEventViewSet(GenericViewSet):
queryset = Event.objects.all()
serializer_class = EventSerializer
filterset_class = EventFilterSet
ordering = ("start_time",)
Я написал этот фрагмент, который, как мне кажется, должен работать, но я не уверен, следует ли его поместить в представление или сериализатор, и как убедиться, что метод действительно вызывается. Я подозреваю, что, возможно, я неправильно смешиваю представления на основе классов и представления на основе функций... так что, возможно, есть лучший способ решить эту задачу.
def check_valid_start_end_search(self, request):
start = request.query_params.get("start_time")
end = request.query_params.get("end_time")
if not start < end:
return Response({"error": "The start time must be after the end time"}, status=HTTP_400_BAD_REQUEST)
Я видел здесь несколько похожих вопросов, но все они касаются представлений на основе функций или обработки одной и той же ошибки, но на поле модели, а не на параметре запроса
You can raise custom errors from your serializers also to validate start time and end time.
try this solution.
class EventSerializer(serializers.ModelSerializer):
start_time = serializers.DateTimeField()
end_time = serializers.DateTimeField()
class Meta:
model = Event
fields = ("start_time", "end_time")
def validate(self,attrs):
start_time=attrs.get('start_time')
end_time=attrs.get('end_time')
if start_time < end_time:
raise serializers.ValidationError('The start time must be after the end time')
return attrs