我使用Django Rest Framework作为应用程序的后端。
我的User
有一个Wallet
。然后我有Item
。如果User
想要Item
,则会在他/她Wallet
中创建一个名为WalletItem
的实例。一切顺利。
现在,我想使用属性User
限制limit_usage
的项目数。
首先,我添加了一个检查以发布方法添加新实例,该实例检查User
的{{1}}中的项目实例数。因此,当尝试为此Wallet
WalletItem
添加第三个limit_usage == 2
时,用户会获得403。
我想在Item
/ get_queryset()
方法中覆盖queryset
方法或list()
,这样,如果匿名用户调用retrieve()
,则会有未过滤的项目响应。但是,如果用户通过身份验证,我只想过滤那些允许放入钱包的项目,即那些未超过当前用户的limit_usage的项目。
/items/
我创建了一个class Wallet(models.Model):
user = models.OneToOneField('auth.User', related_name='wallet')
class Item(models.Model):
valid_from = models.DateTimeField()
valid_to = models.DateTimeField()
limit_usage = models.PositiveSmallIntegerField(default=0)
class WalletItem(models.Model):
wallet = models.ForeignKey('Wallet', related_name='%(class)ss')
offer = models.ForeignKey('Item', related_name='offer')
class ItemViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Item.objects.all().order_by('-created_at')
serializer_class = ItemSerializer
def list(self, request, *args, **kwargs):
time_now = now()
self.queryset = self.queryset.filter(
valid_from__lte=time_now,
valid_to__gte=time_now,
)
serializer = self.get_serializer(self.queryset, many=True)
return Response(serializer.data)
类的方法应该帮助了我,但我意识到我不能在查询集中使用它:
Item
因此,我可以遍历查询集以查看每个项目是否对用户可见,但是我无法从此筛选列表中构造查询集。 我在SO上找到了类似的东西:Django REST Framework : filtering with another table但是回复对我没有帮助。
答案 0 :(得分:3)
首先需要检查用户是否经过身份验证,不是,然后每{}返回} {}。然后,如果相应的Item
对象超出其限制,则过滤掉Item
个对象。
WalletItem
我建议您根据当前时间将过滤移至相同的from django.db.models import Count, F, Sum
...
class ItemViewSet(viewsets.ReadOnlyModelViewSet):
def get_queryset(self):
queryset = super().get_queryset()
user = self.request.user
if user.is_anonymous:
return queryset
queryset = queryset.annotate(user_wallet_items=Sum(
Case(
When(walletitem__wallet_id=user.wallet_id, then=1),
default=0, output_field=IntegerField()
)) \
.filter(user_wallet_items__lte=F('limit_usage'))
return queryset
方法,因为它属于那里。
注意:我没有测试过这种方法。