i have the below config and i would like to map the url field in UserProfileView to the related user's username instead of the default pk field
currently the url looks likes below, appreciate any help
{
"user": 23,
"bio": "My bio",
"created_on": "2020-06-12T21:24:52.746329Z",
"url": "http://localhost:8000/bookshop/bio/8/?format=api"
},
what i am looking for is
{
"user": 23, <--- this is the user <pk>
"bio": "My bio",
"created_on": "2020-06-12T21:24:52.746329Z",
"url": "http://localhost:8000/bookshop/bio/username/?format=api"
},
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
bio = models.CharField(max_length=255)
created_on = models.DateTimeField(auto_now_add=True)
last_updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.user.username
views.py
class UserProfileViewSets(viewsets.ModelViewSet):
authentication_classes = [TokenAuthentication, ]
permission_classes = [rest_permissions.IsAuthenticated, permissions.UserProfileOwnerUpdate, ]
queryset = models.UserProfile.objects.all()
serializer_class = serializers.UserProfileSerializer
renderer_classes = [renderers.AdminRenderer, renderers.JSONRenderer, renderers.BrowsableAPIRenderer, ]
# lookup_field = 'user.username'
def perform_create(self, serializer):
serializer.save(user=self.request.user)
serializer.py
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserProfile
fields = ['user', 'bio', 'created_on', 'url']
extra_kwargs = {
'last_updated': {
'read_only': True
},
'user': {
'read_only': True
},
}
after struggling and reading many articles, I did it and posting down the solution if anybody was looking for the same use case.
The
serializeris aHyperlinkedModelSerializer, as shown below theuserSerializerField isPrimaryKeyRelatedFieldand it is being related to another column/field in theUsermodeluser.username- i made this as the defaultPrimaryKeyRelatedFieldis thepkand i dont want to expose that on theAPIthe
urlkey is customized to beHyperlinkedRelatedFieldto point to the above field - theuserwith a viewnameuser-relatedlookup_fieldto beuserand override the get_object method as now the queryset should be filtered by theusernameEDIT:
I did the requirements in another approach and think this one is more neat way , so below the modifications.
HyperLinkedIdentityFieldwhere you over right thekwargs, check the below kwargs, the value is mapped to the related model where aOneToOneForgienKeydeifinedlookup_fieldwith the kwargs defined in the CustomizedField