为Django中的特定方法设置路由



我正在django中从头开始使用REST API。我的意思是,我不是直接使用DjangRestFramework,但我使用的是基于类的视图和RestFramework中的一些东西。所以,我试图为我所有的演员返回一个GET响应,但问题是我的urls.py中已经有另一个GET回应,用于电影列表,Django返回第一个。你有解决这个问题的办法吗?

这是我的模型、视图和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)

附言:尽管我建议对每个视图使用单独的视图。