如何在drf

时间:2019-12-21 11:28:49

标签: python django django-rest-framework

我有两个模型。房屋和预订。 Reservation通过外键与House相关。

class House(models.Model):
    name = models.CharField(max_length=255)
    description = models.CharField(max_length=1000)

class Reservation(models.Model):
    house = models.ForeignKey(House, on_delete=models.CASCADE)
    check_in = models.DateField()
    check_out = models.DateField()

我的视图中有mixins:

class ReservationList(mixins.ListModelMixin,
                      mixins.CreateModelMixin,
                      generics.GenericAPIView):
    queryset = Reservation.objects.all()
    serializer_class = ReservationSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)


class ReservationDetail(mixins.RetrieveModelMixin,
                        mixins.DestroyModelMixin,
                        generics.GenericAPIView):
    queryset = Reservation.objects.all()
    serializer_class = ReservationSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

我有路线:

urlpatterns = [
    path('reservations/', ...),
    path('houses/<int:pk>/reserve/', ...),
    path('houses/<int:pk>/cancel_reservation/', ...)
]

我想用houses/<int:pk>/reserve/类的方法post连接ReservationListhouses/<int:pk>/cancel_reservation/类的delete方法的ReservationDetail。因此,当用户键入houses/<int:pk>/cancel_reservation url时,drf必须运行delete类的ReservationDetail方法。在路线中写些什么?

1 个答案:

答案 0 :(得分:0)

首先,您不需要拥有两种不同的视图即可满足您的需求。这段代码可以做任何您想做的事情。

from rest_framework import viewsets

class ReservationList(viewsets.ModelViewSet):
    queryset = Reservation.objects.all()
    serializer_class = ReservationSerializer
  

我想将路径Reservations /与ReservationList类的get方法连接。

如果您对/ reservations进行GET请求,则使用视图集将获得一个保留列表。如果要获取特定的预订,则应该对/ reservations / reservation_id进行GET请求。

对于您的问题的下一部分,我认为您不需要为此使用视图。假设您有一个HouseView:

from rest_framework import viewsets
from rest_framework import status

class HouseView(APIView):

@detail_route(methods=['POST'])
def reserve(request,*args,**kwargs):
    house = self.get_object()
    try:
        reservation = ReservationList.objects.get(house=house)
        if reservation.exists():
            return Response(status=status.HTTP_400_BAD_REQUEST)
    except ReservationList.DoesNotExist:
        reservation = Reservation(house=house, 
            check_in=kwargs.get('check_in'), 
            check_out=kwargs.get('checkout')
        )
    return Response(data={'response':'I GOT THE POWAH!'})

@detail_route(methods=['POST'])
def cancel_reservation(request,*args,**kwargs):
    house = self.get_object()
    try:
        reservation = ReservationList.objects.get(house=house)
        reservation.delete()
        return Response(status=status.HTTP_200_OK)
    except ReservationList.DoesNotExist:
        return Response(status=status.HTTP_400_BAD_REQUEST,data={'response':'no such reservation'})

请记住,我不知道您是如何管理/ house相关视图的。这只是一个演示。

,您的urls.py看起来像这样:

from rest_framework.routers import DefaultRouter
from .views import *

custom_router = DefaultRouter()
custom_router.register(r'houses', HouseView, 'houses')
urlpatterns = [*****] # your other urls.
urlpatterns += [
    url(r'/', include(custom_router.urls))]