Django Rest Framework - Получение первичного ключа в теле POST-ответа
Я пытаюсь создать 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>/
GET /events/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/
я получу пустые поля für key
и url
.
Как я могу объединить созданные значения для этих двух полей? Они являются обязательными для перехода к детальному представлению.
Вы можете создать новый сериализатор событий для метода create, который не будет устанавливать ключ как read_only, и использовать его для метода create. Переопределите get_serializer_class в вашем представлении, чтобы выбрать правильный сериализатор в зависимости от случая.
def get_serializer_class(self):
if self.action != "skills":
return CreateEventSerializer
return super().get_serializer_class()
Что касается url, я предполагаю, что вы не получаете его обратно, потому что это не поле модели. Надеюсь, это немного поможет.
Один из способов решения этой проблемы - вернуть объект из 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)