Установка маршрута для определенного метода в Django
Я работаю с REST API в django с нуля. То есть, я не работаю с DjangoRestFramework напрямую, но я использую Class-BasedViews и некоторые вещи из RestFramework. Итак, я пытаюсь вернуть GET-ответ для всех моих актеров, но проблема в том, что у меня уже есть другой GET-ответ в моем urls.py для списка фильмов, а Django возвращает того, кто первый. Есть ли у вас идеи, как это решить?
Вот мои Models, Views и urls.py
class Actor(models.Model):
full_name = models.CharField(max_length=125)
role = models.CharField(max_length=125)
def __str__(self):
return self.full_name
@classmethod
def find_actors(cls):
actors = Actor.objects.all().order_by('pk')
actors_list = []
for actor in actors:
actors_list.append({
"full_name": actor.full_name,
})
return actors_list
class Movie(models.Model):
ACTION = 'AC'
DRAMA = 'DR'
COMEDY = 'CM'
SCIENCE_FICTION = 'SF'
THRILLER = 'TR'
RELIGIOUS = 'RG'
GENRE_CHOICES = [
(ACTION, 'Accion'),
(DRAMA, 'Drama'),
(COMEDY, 'Comedy'),
(SCIENCE_FICTION, 'Ciencia Ficcion'),
(THRILLER, 'Triler'),
(RELIGIOUS, 'Religioso')
]
title = models.CharField(max_length=155, blank=False)
synopsis = models.TextField(max_length=1000, blank=True)
genre = models.CharField(max_length=100, choices=GENRE_CHOICES, default='', blank=False)
tag = models.JSONField(default=dict, blank=True)
actors = models.ManyToManyField(Actor, related_name='movies', blank=True)
def __str__(self):
return self.title
@classmethod
def find_all_movies(cls):
movies = Movie.objects.filter(actors__isnull=False).distinct().order_by('pk')
movie_list = []
for movie in movies:
movie_list.append({
"id": movie.id,
"title": movie.title,
"synopsis": movie.synopsis,
"genre": movie.genre,
"tag": movie.tag,
"actors": list(movie.actors.all().values('full_name', 'role'))
})
return movie_list
views.py
class MovieView(APIView):
permission_classes = [IsAuthenticated]
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
def get(self, request, pk=0):
"""
Return the list of all movies, or a single movie
:param pk:
:param request:
:return:
"""
if pk > 0:
movies = list(Movie.objects.filter(pk=pk).values())
if len(movies) > 0:
movie = movies[0]
data = {'message': "Success", 'movie': movie}
else:
data = {'message': "Movie not found... "}
return Response(data)
else:
movies = Movie.find_all_movies()
if len(movies) > 0:
data = {'message': "Success", 'movies': movies}
else:
data = {'message': "Movies not found ..."}
return Response(data)
def get_list_of_actors(self, request):
actors = Actor.find_actors()
if len(actors) > 0:
data = {'message': "Success", 'actors': actors}
else:
data = {'message': "Actors not found..."}
return Response(data)
urls.py
from django.urls import path
from .views import *
urlpatterns = [
path('movies/', MovieView.as_view(), name='movies-list'),
path('create-new-movie/', MovieView.as_view(), name='create-new-movie'),
path('movie-detail/<int:pk>/', MovieView.as_view(), name='movie-detail'),
path('update-movie/<int:pk>/', MovieView.as_view(), name='update-movie'),
path('delete-movie/<int:pk>/', MovieView.as_view(), name='delete-movie'),
path('actors/', MovieView.as_view(), name='actors-list'),
]
Вы можете наложить условие на ваш метод get
, и решить, какой результат возвращать в зависимости от пути url.
def get(self, request, pk=0):
if request.path_info == '/movies/':
return self.get_list_of_movies(request, pk)
elif request.path_info == '/actors/':
return self.get_list_of_actors(request)
def get_list_of_movies(self, request, pk):
"""
Return the list of all movies, or a single movie
:param pk:
:param request:
:return:
"""
if pk > 0:
movies = list(Movie.objects.filter(pk=pk).values())
if len(movies) > 0:
movie = movies[0]
data = {'message': "Success", 'movie': movie}
else:
data = {'message': "Movie not found... "}
return Response(data)
else:
movies = Movie.find_all_movies()
if len(movies) > 0:
data = {'message': "Success", 'movies': movies}
else:
data = {'message': "Movies not found ..."}
return Response(data)
def get_list_of_actors(self, request):
actors = Actor.find_actors()
if len(actors) > 0:
data = {'message': "Success", 'actors': actors}
else:
data = {'message': "Actors not found..."}
return Response(data)
P.S. Хотя я рекомендую использовать отдельные представления для каждого из них.