I am using Django Rest Framework as a backend for an app.
I have a User that has one Wallet. Then I have Item. If a User wants an Item it creates an instance in his/her Wallet called WalletItem. All works well.
Now I want to limit the number of items for the User using an attribute limit_usage.
First, I added a check to post method adding new instance that checks the number of item instances in User's Wallet. So the user gets 403 when trying to add third WalletItem if limit_usage == 2 for this Item.
I would like to override a get_queryset() method or queryset in list()/retrieve() methods so that if anonymous user calls /items/ there are unfiltered items in response. However if the user is authenticated I would like to filter only those Items that s/he is allowed to put in the Wallet, i.e. those that have not exceeded limit_usage for current user.
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)
I created a method of Item class that should have helped me but I realized I cannot use it in the queryset:
def is_visible_for_user(self, user=None):
if not self.limit_usage or not user:
return True
ct = WalletItem.objects.filter(item=self, wallet=user.wallet).count()
return self.limit_usage > ct
So I can iterate through the queryset to see if each item can be visible for the user, however I cannot construct the queryset out of this filtered list. I found something similar here on SO: Django REST Framework : filtering with another table but the response did not help me.