#python #django #django-models #django-rest-framework #django-views
Вопрос:
Я пытаюсь создать rest api с помощью Django Restframework. В этом Api я использую модель под названием Event
.
models.py
class Event(models.Model):
key = models.IntegerField(auto_created=True, primary_key=True)
start_date = models.DateTimeField()
end_date = models.DateTimeField()
subject = models.TextField(max_length=250)
description = models.TextField(max_length=2500)
created = models.DateTimeField(default=django.utils.timezone.now)
host = models.ForeignKey('auth.User', related_name='host', on_delete=models.CASCADE, null=True)
serializers.py
class EventSerializer(serializers.HyperlinkedModelSerializer):
host = serializers.StringRelatedField()
key = serializers.IntegerField(read_only=True)
class Meta:
model = Event
fields = ['url', 'key', 'start_date', 'end_date', 'subject', 'description', 'host']
views.py
class EventViewSet(viewsets.ModelViewSet):
queryset = Event.objects.all()
serializer_class = EventSerializer
@action(detail=True)
def skills(self, request, *args, **kwargs):
return get_key_values(TblClsOne=EventSkills, TblClsTwo=Skills, table_one_column_name="event_id",
table_one_fk_name='skill_id', table_two_column_name="skill_id",
table_one_filter_value=kwargs["pk"])
def perform_create(self, serializer):
serializer.save(host=self.request.user)
Когда я хочу узнать подробности о событии, я звоню GET /events/<id>/
ПОЛУЧИТЬ /события/502/ Пример
{
"url": "http://127.0.0.1:8000/events/502/",
"key": 502,
"start_date": "2021-09-23T20:00:00Z",
"end_date": "2021-09-23T21:00:00Z",
...
"host": null
}
Но если я создам новое событие с помощью POST /events/
Я получу пустые поля для key
и url
.
Как я могу интегрировать созданные значения для этих двух полей? Они обязательны для перехода к подробному представлению.
Ответ №1:
Один из способов решить эту проблему-вернуть объект из perform_create
, переопределить create
и снова использовать созданный объект в сериализаторе, как это:
class EventViewSet(viewsets.ModelViewSet):
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
obj = self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(self.get_serializer(obj).data, status=status.HTTP_201_CREATED, headers=headers)
def perform_create(self, serializer):
return serializer.save(host=self.request.user)
Ответ №2:
Вы можете создать новый сериализатор событий для использования в методе create, который не устанавливает ключ как read_only, и использовать его для метода create. Переопределите класс get_serializer_класс в вашем представлении, чтобы выбрать правильный сериализатор в зависимости от случая.
def get_serializer_class(self):
if self.action != "skills":
return CreateEventSerializer
return super().get_serializer_class()
Что касается URL-адреса, я предполагаю, что вы не получите его обратно, потому что это не поле модели. Я надеюсь, что это немного поможет.
Комментарии:
1. спасибо за ваше вдохновение. К сожалению, я не получу ключ в теле ответа
POST /event/
. У вас есть какие-нибудь идеи, как это может сработать?