Ich verwende Django Rest Framework als Backend für eine App.Django Rest Framework: Erweiterte Abfragefilterung basierend auf einem anderen Modell
Ich habe eine User
, die eine Wallet
hat. Dann habe ich Item
. Wenn ein User
einen Item
will, erstellt er eine Instanz in seinem Wallet
namens WalletItem
. Alles funktioniert gut.
Jetzt möchte ich die Anzahl der Elemente für die User
mit einem Attribut limit_usage
begrenzen.
Zuerst fügte ich eine Prüfung zu post-Methode hinzu, die neue Instanz hinzufügt, die die Anzahl der Element-Instanzen in User
's Wallet
überprüft. So erhält der Benutzer 403, wenn er versucht, das dritte WalletItem
hinzuzufügen, wenn limit_usage == 2
für dieses Item
.
Ich mag würde eine get_queryset()
Methode oder queryset
in list()
/retrieve()
Methoden außer Kraft zu setzen, so dass, wenn anonyme Benutzer rufen /items/
es ungefiltert Artikel sind in der Antwort. Wenn der Benutzer jedoch authentifiziert wird, möchte ich nur die Elemente filtern, die er in das Wallet legen darf, d. H. Diejenigen, die limit_usage für den aktuellen Benutzer nicht überschritten haben.
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)
habe ich eine Methode der Item
Klasse, die mir geholfen haben sollte, aber ich merkte, ich nicht, dass es in der queryset verwenden:
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 kann ich durch die queryset laufen, wenn jedes Einzelteil kann zu sehen Für den Benutzer sichtbar sein, aber ich kann das Abfrage-Set nicht aus dieser gefilterten Liste erstellen. Ich fand etwas ähnliches hier auf SO: Django REST Framework : filtering with another table, aber die Antwort hat mir nicht geholfen.
Vielen Dank, es funktioniert wie ein Charme. Ich habe nur 'Q (limit_usage = 0)' hinzugefügt, um die Gegenstände zu decken, die keine Begrenzung haben. Dank Ihrer Antwort entdeckte ich ganz neue Welt von [bedingte Ausdrücke] (https://docs.djangoproject.com/en/1.11/ref/models/conditional-expressions/) –
@ JurajBezručka Sie sind willkommen, ich entdeckte die gleiche Weile Ich habe mich darauf vorbereitet zu antworten :) –