So I've built an API for movies dataset
which contain following structure:
Models.py
class Directors(models.Model):
id = models.IntegerField(primary_key=True)
first_name = models.CharField(max_length=100, blank=True, null=True)
last_name = models.CharField(max_length=100, blank=True, null=True)
class Meta:
db_table = 'directors'
ordering = ['-id']
class Movies(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=100, blank=True, null=True)
year = models.IntegerField(blank=True, null=True)
rank = models.FloatField(blank=True, null=True)
class Meta:
db_table = 'movies'
ordering = ['-id']
class Actors(models.Model):
id = models.IntegerField(primary_key=True)
first_name = models.CharField(max_length=100, blank=True, null=True)
last_name = models.CharField(max_length=100, blank=True, null=True)
gender = models.CharField(max_length=20, blank=True, null=True)
class Meta:
db_table = 'actors'
ordering = ['-id']
class DirectorsGenres(models.Model):
director = models.ForeignKey(Directors,on_delete=models.CASCADE,related_name='directors_genres')
genre = models.CharField(max_length=100, blank=True, null=True)
prob = models.FloatField(blank=True, null=True)
class Meta:
db_table = 'directors_genres'
ordering = ['-director']
class MoviesDirectors(models.Model):
director = models.ForeignKey(Directors,on_delete=models.CASCADE,related_name='movies_directors')
movie = models.ForeignKey(Movies,on_delete=models.CASCADE,related_name='movies_directors')
class Meta:
db_table = 'movies_directors'
ordering = ['-director']
class MoviesGenres(models.Model):
movie = models.ForeignKey(Movies,on_delete=models.CASCADE,related_name='movies_genres')
genre = models.CharField(max_length=100, blank=True, null=True)
class Meta:
db_table = 'movies_genres'
ordering = ['-movie']
class Roles(models.Model):
actor = models.ForeignKey(Actors,on_delete=models.CASCADE,related_name='roles')
movie = models.ForeignKey(Movies,on_delete=models.CASCADE,related_name='roles')
role = models.CharField(max_length=100, blank=True, null=True)
class Meta:
db_table = 'roles'
ordering = ['-actor']
urls.py
from django.urls import path, include
from . import views
from api.views import getMovies, getGenres, getActors
urlpatterns = [
path('', views.getRoutes),
path('movies/', getMovies.as_view(), name='movies'),
path('movies/genres/', getGenres.as_view(), name='genres'),
path('actor_stats/<pk>', getActors.as_view(), name='actor_stats'),
]
serializer.py
from rest_framework import serializers
from movies.models import *
class MoviesSerializer(serializers.ModelSerializer):
class Meta:
model = Movies
fields = '__all__'
class DirectorsSerializer(serializers.ModelSerializer):
class Meta:
model = Directors
fields = '__all__'
class ActorsSerializer(serializers.ModelSerializer):
class Meta:
model = Actors
fields = '__all__'
class DirectorsGenresSerializer(serializers.ModelSerializer):
class Meta:
model = DirectorsGenres
fields = '__all__'
class MoviesDirectorsSerializer(serializers.ModelSerializer):
movie = MoviesSerializer(many = False)
director = DirectorsSerializer(many = False)
class Meta:
model = MoviesDirectors
fields = '__all__'
class MoviesGenresSerializer(serializers.ModelSerializer):
movie = MoviesSerializer(many = False)
class Meta:
model = MoviesGenres
fields = '__all__'
class RolesSerializer(serializers.ModelSerializer):
movie = MoviesSerializer(many = False)
actor = ActorsSerializer(many = False)
class Meta:
model = Roles
fields = '__all__'
views.py
class getMovies(ListAPIView):
directors = Directors.objects.all()
queryset = MoviesDirectors.objects.filter(director__in=directors)
serializer_class = MoviesDirectorsSerializer
pagination_class = CustomPagination
filter_backends = [DjangoFilterBackend]
filterset_fields = ['director__first_name', 'director__last_name']
class getGenres(ListAPIView):
movies = Movies.objects.all()
queryset = MoviesGenres.objects.filter(movie__in=movies).order_by('-genre')
serializer_class = MoviesGenresSerializer
pagination_class = CustomPagination
filter_backends = [DjangoFilterBackend]
filterset_fields = ['genre']
class getActors(ListAPIView):
queryset = Roles.objects.all()
serializer_class = RolesSerializer
pagination_class = CustomPagination
def get_queryset(self):
return super().get_queryset().filter(
actor_id=self.kwargs['pk']
)
Now I want to count number of movies by genre that actor with specific pk played in getActors
class. Like the number of movies by genre that actor participated in. E.g. Drama: 2, Horror: 3 Right now I am getting the overall count of movies count: 2
:
GET /api/actor_stats/17
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": 800480,
"movie": {
"id": 105231,
"name": "Everybody's Business",
"year": 1993,
"rank": null
},
"actor": {
"id": 17,
"first_name": "Luis Roberto",
"last_name": "Formiga",
"gender": "M"
},
"role": "Grandfather"
},
{
"id": 800481,
"movie": {
"id": 242453,
"name": "OP Pro 88 - Barra Rio",
"year": 1988,
"rank": null
},
"actor": {
"id": 17,
"first_name": "Luis Roberto",
"last_name": "Formiga",
"gender": "M"
},
"role": "Himself"
}
]
}
What is the optimized way of achieving the following:
- number_of_movies_by_genre
- Drama: 2
- Horror: 3
UPDATE
I was able to add actor id and movie id in serializers:
class RolesSerializer(serializers.ModelSerializer):
movie = MoviesSerializer(many = False)
actor = ActorsSerializer(many = False)
movie_id = serializers.SerializerMethodField()
actor_id = serializers.SerializerMethodField()
class Meta:
model = Roles
fields = '__all__'
def get_movie_id(self, obj):
return obj.movie_id
def get_actor_id(self, obj):
return obj.actor.id
result:
{
"next": null,
"previous": null,
"count": 2,
"pagenum": null,
"results": [
{
"id": 800480,
"movie": {
"id": 105231,
"name": "Everybody's Business",
"year": 1993,
"rank": null
},
"actor": {
"id": 17,
"first_name": "Luis Roberto",
"last_name": "Formiga",
"gender": "M"
},
"movie_id": 105231,
"actor_id": 17,
"role": "Grandfather"
},
{
"id": 800481,
"movie": {
"id": 242453,
"name": "OP Pro 88 - Barra Rio",
"year": 1988,
"rank": null
},
"actor": {
"id": 17,
"first_name": "Luis Roberto",
"last_name": "Formiga",
"gender": "M"
},
"movie_id": 242453,
"actor_id": 17,
"role": "Himself"
}
]
}
Now I don't know how to even count in how many movies actor with specific id played so to able even go further and get number of movies by genre.
from Is there a way to add custom data into ListAPIView in django rest framework
No comments:
Post a Comment