I try to build a rest api with Django Restframework. In this Api i use a Model called 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)
When I want to see the Details from a event i call GET /events/<id>/
GET /events/502/ Example
{
"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
}
But if I create a new Event via POST /events/
I will receive empty fields for key
and url
.
How can I integrate the created values for these two fields? They are mandatory for navigating to the detail view.
CodePudding user response:
You can create a new event serializer to use for the create method that doesnt set the key as read_only and use it for the create method. Overide the get_serializer_class in your view to select the correct serializer depending on the case.
def get_serializer_class(self):
if self.action != "skills":
return CreateEventSerializer
return super().get_serializer_class()
As for the url I am guessing you are not getting it back because it is not a model field. I hope this helps a bit.
CodePudding user response:
One way to solve this is to return the object from perform_create
, and override create
and use the created object on the serializer again like this:
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)