Установка маршрута для определенного метода в 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. Хотя я рекомендую использовать отдельные представления для каждого из них.

Вернуться на верх