Hi All,
I’m building an endpoint with Django Rest Framework which is used for CRUD operation on a user’s settings.
class UserSetting(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
user = models.OneToOneField(CustomUser, related_name="settings", on_delete=models.CASCADE)
settings = JSONField(null=True, blank=True)
I was going to use a viewset, but since I know the user via request.user
and my queryset will always be a get_object_or_404
I thought I’d just use generics.RetrieveUpdateDestroyAPIView
as opposed to having to pass an identifier for a retrieve request, to user/settings/identifier
like one would when using a viewset.
As an example, I would like the URL user/settings
to:
- GET a single object that is the
request.user
's setting object - POST that will create a
UserSetting
object forrequest.user
- PUT/PATCH that will update
request.user
'sUserSetting
object - DELETE to delete
request.user
'sUserSetting
object
In order to get the user from the request, I have overriden save()
in my serialiser to get the user from the request context:
def save(self, **kwargs):
user = None
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
kwargs["user"] = user
return super().save(**kwargs)
And everything seemed to work just fine and dandy until I realised I can’t POST to my endpoint, only GET, PUT, PATCH, and DELETE.
I tried adding CreateModelMixin
to my view, but that didn’t seem to help.
class UserSettingsViewset(CreateModelMixin, generics.RetrieveUpdateDestroyAPIView):
From what I have worked out so far is, that it looks like I’ll have to create a separate endpoint for POST requests that will create a UserSetting
.
So, with the long story out of the way, does anybody know how to create a single endpoint that can do all of CRUD at a single URL?
I suppose in the worst case I could do something like use a Viewset and use the user.username as a lookup field, but that is just a guess at an idea whilst I write this.
Any thoughts how I can tackle my problem? Or if it is even a good idea to be tackling such a problem?
Cheers,
C