0

I have two models (customer, movie) and I would like to return (movie_name, customer_name, id) when I hit the URL (api/customer/1) and when I hit the URL (api/customer/1/movies) just wanted the movie names alone. How can we achieve this ?

models.py

class Customer(models.Model):
    name = models.CharField(max_length=200, null=True)

class Movie(models.Model):
    movie_name = models.CharField(max_length=200, null=True)
    customer = models.ForeignKey(Customer, null=True, on_delete=models.SET_NULL)

serializers.py

class CustomerSerializer(serializers.ModelSerializer):

    class Meta:
        model = Customer
        fields = ('id', 'name')

class MovieSerializer(serializers.ModelSerializer):

    class Meta:
        model = Movie
        fields = '__all__'

urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^api/customers/$', CustomerSerializer.as_view(), name='customers'),
]

Note:

  • At the moment, when I hit the URL (api/customers) it returns the id, name of all the customers. Now, I would like to know, when I hit the URL (api/customer/1) how to list the same information along with movie names and when I hit the URL (api/customer/1/movies) how to just return the movie names alone?

enter image description here

1 Answer 1

2

You will have to write two urls for this purpose but you can do this with one view and serializer like this

Urls

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/customers/<int:id>/', CustomerMovieView.as_view(check=True)),
    path('api/customers/<int:id>/movies/', CustomerMovieView.as_view(check=False)),
]

Views and Serializers

from rest_framework import generics, response, serializer


class MovieSerializer(serializers.ModelSerializer):
     customer_name = serializers.SerializerMethodField()
     def get_customer_name(self, instance):
         return instance.customer.name

     class Mete:
         model = Movie
         fields = '__all__'

     def to_representation(self, instance):
         data = super().to_representation(instance)
         if not self.context('check'):
             data.pop('customer_name', None)
             data.pop('customer', None)
         return data


class CustomerMovieView(generics.GenericAPIView):
     serializer_class = MovieSerializer
     check = True
     
     def get_serializer_context(self):
         context = super().get_serializer_context()
         context.update({'check': self.check})
         return context

     def get(self, request, *args, **kwargs):
         id = kwargs.get('id')
         movie = Movie.objects.get(id=id)
         serialized = self.get_serializer(movie)
         return response.Respoonse(serialized.data)
         
Sign up to request clarification or add additional context in comments.

9 Comments

Hi, I am getting "AttributeError: module 'rest_framework.generics' has no attribute 'GenericApiView'" error message. Also can explain me what you are referring here as "ViewSerializer" ?
It was a spelling mistake. Check now.
Thanks for helping.. But few things are bit confusing as I am new to django.. As I have asked earlier, what you are referring here as ViewSerializer? Because I am getting "NameError: name 'ViewSerializer' is not defined"
Sorry to bother you again, but what is this line "customer_name = serializers.SerializerMethodField()" referring to?
Bit Confused, can you please rename with my actual serializer names given in my original questions?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.