我正在尝试在django网站上实现播放按钮的api版本。
这就是我走多远:
models.py
class Note(models.Model):
plays = models.ManyToManyField(settings.AUTH_USER_MODEL,blank=True,related_name='track_plays')
def get_play_url(self):
return "/play/{}/play".format(self.pk)
def get_api_like_url(self):
return "/play/{}/play-api-toggle".format(self.pk)
views.py
class TrackPlayToggle(RedirectView):
def get_redirect_url(self,*args,**kwargs):
id = self.kwargs.get("id")
obj = get_object_or_404(Note,id=id)
url_ = obj.get_absolute_url()
user = self.request.user
if user.is_authenticated():
if user in obj.plays.all():
obj.plays.add(user)
else:
obj.plays.add(user)
return url_
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication,permissions
from rest_framework.decorators import api_view
class TrackPlayAPIToggle(RedirectView):
authentication_classes = (authentication.SessionAuthentication,)
permission_classes = (permissions.IsAuthenticated,)
@api_view(['GET', 'POST', ])
def get(self,request,format=None):
obj = get_object_or_404(Note,id=id)
url_ = obj.get_absolute_url()
user = self.request.user
updated = False
played = False
if user.is_authenticated():
if user in obj.plays.all():
played = True
obj.plays.add(user)
else:
played = True
obj.plays.add(user)
played = False
updated = True
data = {
"updated":updated,
"played":played
}
return Response(data)
urls.py
url(r'^(?P<id>d+)/play/', TrackPlayToggle.as_view(), name='play-toggle'),
url(r'^api/(?P<id>d+)/play/', TrackPlayAPIToggle.as_view(), name='play-api-toggle'),
我添加了 API 装饰器,因为没有它,我会收到一个类型错误:
get() got an unexpected keyword argument 'id'
当我尝试添加id=None时,我得到一个断言错误:
.accepted_renderer not set on Response
这是因为我使用了 id 而不是 slug 吗?
感谢您的任何建议
我不明白为什么你认为添加@api_view
装饰器可以解决你的TypeError。该装饰器用于基于函数的视图;它在基于类的视图中没有用处,在基于类的视图中,您只需定义相关方法即可定义支持哪些方法。拆下装饰器。
解决原始问题的方法是将id
参数添加到方法中;而用渲染器解决问题的方法是从正确的父类继承,这显然不应该是 RedirectView。
class TrackPlayAPIToggle(GenericAPIView):
authentication_classes = (authentication.SessionAuthentication,)
permission_classes = (permissions.IsAuthenticated,)
def get(self, request, id, format=None):
...