【问题标题】:Call Method in Model Class Based view基于模型类的视图中的调用方法
【发布时间】:2021-06-18 12:42:04
【问题描述】:

我的模型中有方法可以在 API 中调用。

型号:

class Booking(models.Model):
    PENDING = 'PN'
    ACCEPTED = 'AC'
    DENIED = 'DN'
    BOOKING_STATUS_CHOICES = [
        (PENDING, 'Pending'),
        (ACCEPTED, 'Accepted'),
        (DENIED, 'Denied')
    ] 
    createdDate = models.DateTimeField(auto_now_add=True)
    comments = models.CharField(max_length=120)
    location = models.TextField()
    date = models.DateTimeField()
    operator = models.ForeignKey("Business", on_delete=models.CASCADE)
    status = models.CharField(max_length=2, choices=BOOKING_STATUS_CHOICES,default=PENDING)

    def __str__(self):
        return self.comments
    
    def acceptBooking(self):
        self.status = self.ACCEPTED

    def denyBooking(self):
        self.status = self.DENIED

序列化器:

class BookingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Booking
        fields = ('createdDate', 'comments', 'location', 'date', 'operator', 'status')

观看次数:

class BookingView(viewsets.ModelViewSet):
    serializer_class = BookingSerializer
    queryset = Booking.objects.all()
    filter_backends = [filters.SearchFilter]
    search_fields = ['createdDate', 'comments', 'location', 'date', 'operator']

我想调用acceptBooking 或denyBooking。实现这一目标的最佳做法是什么?

谢谢!

【问题讨论】:

标签: python django django-models django-rest-framework django-views


【解决方案1】:

一种选择是将extra actions 添加到您的视图中。因此,某人可以通过执行以下 HTTP 请求之一来接受或拒绝预订:

PUT /bookings/1/accept/
PUT /bookings/1/deny/

您可以通过以下方式实现此目的:

# models.py
class Booking(models.Model):
    ...
    def accept(self):
        self.status = self.ACCEPTED
        self.save()
    
    def deny(self):
        self.status = self.DENIED
        self.save()
# views.py
from rest_framework.decorators import action
from rest_framework.response import Response

class BookingView(viewsets.ModelViewSet):
    ...
    @action(detail=True, methods=['put', 'patch'])
    def accept(self, request, pk=None):
        booking = self.get_object()
        booking.accept()
        return Response({'status': booking.status})
    
    @action(detail=True, methods=['put', 'patch'])
    def deny(self, request, pk=None):
        booking = self.get_object()
        booking.deny()
        return Response({'status': booking.status})

【讨论】:

    【解决方案2】:

    看起来您唯一的问题是模型函数中缺少self.save()。序列化程序会自动为您保存状态,而无需使用所需的功能。

    如果这不是您要查找的内容并且您想要调用函数,那么正如@Ram 提到的,请查看如何调用模型字段。对你来说,这将是:

    class BookingView(viewsets.ModelViewSet):
        serializer_class = BookingSerializer
        queryset = Booking.objects.all()
        filter_backends = [filters.SearchFilter]
        search_fields = ['createdDate', 'comments', 'location', 'date', 'operator']
    
        def perform_update(self, serializer):
            serializer.save()
            if <accept_check>:
                serializer.instance.acceptBooking()
    
            if <deny_check>:
                serializer.instance.denyBooking()
    

    您还必须保存对模型函数的更改,例如:

        def acceptBooking(self):
            self.status = self.ACCEPTED
            self.save()
    
        def denyBooking(self):
            self.status = self.DENIED
            self.save()
    

    请注意函数应使用下划线,因此acceptBooking 应为accept_booking

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-27
      • 2013-02-04
      • 1970-01-01
      • 1970-01-01
      • 2022-11-20
      相关资源
      最近更新 更多