显示特定买家联系的租金清单

时间:2017-03-27 13:32:05

标签: python django django-rest-framework

我是django-rest-framework的初学者。我正在努力了解序列化器和良好的api设计。我不想直接潜入视图集和泛型视图,如ListView,RetrieveAPIView等。我想清楚地理解序列化器和APIView所以我提出了以下标准来解决它们。但是我只能从下面解决2个问题。

以下是我用来磨练其余api技能的问题清单

"""
  return a list of rent
"""

"""
    return a list of rent or specific rent if token is give n
"""

"""
  return a list of rent contacted by specific buyer
"""

"""
  return a list of buyer that has contacted a specific rent
"""

这是我的租借,画廊和联系模式。租赁和联系是单独的应用程序。联系方式是联系租赁所有者以购买或租用该所有者列出的空间。

class Rental(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=300, blank=False, null=False)
    phone_number = models.PositiveIntegerField(null=False, blank=False)
    rate = models.FloatField()


class Gallery(models.Model):
    rent = models.ForeignKey(Rental, related_name="galleries")
    image = models.FileField(upload_to=user_directory_path, null=True, blank=True)
    tag = models.CharField(max_length=1, choices=TAGS, null=True, blank=True)


BUYER_CHOICES = (
  ('B', 'Buy'),
  ('R', 'Rent'),
)

class Contact(models.Model):
    buyer = models.ForeignKey(User)
    rental = models.ForeignKey(Rental, related_name="rent")
    email_id = models.EmailField(blank=False, null=False)
    buyer_choice = models.CharField(choices=BUYER_CHOICES, max_length=1, null=False, blank=False)


class GallerySerializer(serializers.ModelSerializer):
    class Meta:
        model = Gallery
        fields = ('image', 'tag',)

class RentalSerializer(serializers.ModelSerializer):
    user = serializers.ReadOnlyField(source='user.username')
    galleries = GallerySerializer(many=True)
    class Meta:
        model = Rental
        fields = ('__all__')

更新RentAPIView CODE AS PER @Remi

class RentAPIView(APIView):
  serializer_class = RentalSerializer
  parser_classes = (FormParser, MultiPartParser,)
  def get(self, request, token=None, format=None):
    """
     Returns a list of rents (or just rent if token is given)
    """
    reply = {}
    try:
        rents = Rental.objects.filter(user=request.user)
        # code is updated here 
        buyer_id = self.request.query_params.get('buyer_id', None)
        if buyer_id:
            rents = rents.filter(user__contact_set__buyer_id=buyer_id)
        if token:
            rent = rents.get(id=token)
            reply['data'] = RentalSerializer(rent).data
        else:
            reply['data'] = RentalSerializer(rents, many=True).data
    except Rental.DoesNotExist:
        return error.RequestedResourceNotFound().as_response()
    except:
        return error.UnknownError().as_response()
    else:
        return Response(reply, status.HTTP_200_OK)

很抱歉发布长代码。我只是想表明我尽力设计有效的休息api但无法解决最后两个问题。

有谁可以帮助我理解如何处理以下标准?

1 个答案:

答案 0 :(得分:0)

我强烈建议使用viewsets。在您的情况下,如果您覆盖get_queryset函数,ModelViewSet将执行此操作,以便按您想要的任何内容预过滤查询集。例如:

class RentAPIViewset(viewsets.ModelViewSet):
    serializer_class = RentalSerializer

    def get_queryset(self):
        # if requesting something like /api/rent?buyer_id=1
        buyer_id = self.request.query_params.get('buyer_id', None)
        if buyer_id:
            return Rental.objects.filter(rent__buyer__id=buyer_id)
        return Rental.objects.all()

这将更清洁地使用DRF的核心功能。话虽如此,回到你的问题,你可以使用上面的一些逻辑来扩展你的api视图:

带有查询参数的

(您也可以像使用令牌一样使用kwargs方法):

class RentAPIView(APIView):
    serializer_class = RentalSerializer
    parser_classes = (FormParser, MultiPartParser,)
    def get(self, request, token=None, format=None):
        """
         Returns a list of rents (or just rent if token is given)
        """
        reply = {}
        try:
            # first of your two remaining problems
            # if requesting something like /api/rent?buyer_id=1
            buyer_id = self.request.query_params.get('buyer_id', None)

            rents = Rental.objects.filter(user=request.user)

            if buyer_id:
                rents = rents.filter(rent__buyer__id=buyer_id)

            if token:
                rent = rents.get(id=token)
                reply['data'] = RentalSerializer(rent).data
            else:
                reply['data'] = RentalSerializer(rents, many=True).data
        except Rental.DoesNotExist:
            return error.RequestedResourceNotFound().as_response()
        except:
            return error.UnknownError().as_response()
        else:
            return Response(reply, status.HTTP_200_OK)

你的最后一个问题不是返回Rent-Objects,而是返回User对象,所以这应该在不同的API视图中完成。