I've got two models: User and Ticket. Ticket has one User, User has many Tickets
I've accomplished that when i go to url /users/1/tickets, i'm getting the list of user's tickets.
I want to use hyperlinked relations, and here is what i see in my User model representation:
"tickets": [
"http://127.0.0.1:8000/tickets/5/",
"http://127.0.0.1:8000/tickets/6/"
]
But I want it to be like
"tickets": "http://127.0.0.1:8000/users/1/tickets"
Is there a way to do that with DRF?
The url:
url(r'^users/(?P<user_pk>\d+)/tickets/$',
views.TicketsByUserList.as_view(),
name='myuser-tickets'),
The view:
class TicketsByUserList(generics.ListAPIView):
model = Ticket
serializer_class = TicketSerializer
def get_queryset(self):
user_pk = self.kwargs.get('user_pk', None)
if user_pk is not None:
return Ticket.objects.filter(user=user_pk)
return []
User serializer (i tried to play with tickets field definition, changing type, view_name, but with no effect):
class UserSerializer(serializers.HyperlinkedModelSerializer):
tickets = serializers.HyperlinkedRelatedField(many=True, view_name='ticket-detail')
class Meta:
model = MyUser
fields = ('id', 'nickname', 'email', 'tickets')
Ticket serializer:
class TicketSerializer(serializers.HyperlinkedModelSerializer):
user = serializers.HyperlinkedRelatedField(view_name='myuser-detail')
liked = serializers.Field(source='liked')
class Meta:
model = Ticket
fields = ('id', 'user', 'word', 'transcription', 'translation', 'liked', 'created', 'updated')
The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.
Hyperlinking will generate hyperlink for that field lets say ModelA has ModelB with pk =1. If we hyperlink then there will be link referencing to ModelB like. http://example/api/wdawwawda. that will make ModelB discoverable through link and improve cohesion. i.e. ModelA viewed as whole with valid links instead of pks.
In function-based views, we can pass extra context to serializer with “context” parameter with a dictionary. To access the extra context data inside the serializer we can simply access it with “self. context”. From example, to get “exclude_email_list” we just used code 'exclude_email_list = self.
A link relation is a descriptive attribute attached to a hyperlink in order to define the type of the link, or the relationship between the source and destination resources.
You can use a SerializerMethodField to customize it. Something like this:
class UserSerializer(serializers.HyperlinkedModelSerializer):
tickets = serializers.SerializerMethodField('get_tickets')
def get_tickets(self, obj):
return "http://127.0.0.1:8000/users/%d/tickets" % obj.id
class Meta:
model = MyUser
fields = ('id', 'nickname', 'email', 'tickets')
I hard-wired the URL in there for brevity, but you can do a reverse lookup just as well. This basically just tells it to call the get_tickets
method instead of the default behavior in the superclass.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With