I have two models: the first is named Card
and has a foreign key (named owner
) to the second model (User
). I'm trying to write a view that lists all the Cards owned by a User, the client selects the User by changing the URL (not query parameters).
For example, if I make a GET request to /cards/by-user-id/42/
, I should get all the Cards owned by the User whose id is 42.
From what I understood, it is possible to achieve this by using an URL pattern like this : path('cards/by-user-id/<int:user_id>', my_view.as_view())
and then in the viewset I can use self.kwargs['user_id']
to get the id and then filter the data. However, I can't find how to do it using routers (more appropriated for djangorestframework). I tried with <int:user_id>
in the prefix but it does not pick it up, it just considers it as a normal string, so not only the URL is incorrect (I have to type literally /cards/by-user-id/<int:user_id>/
) but also kwargs
doesn't contain 'user_id'.
Here is what I tried:
models.py:
from django.contrib.auth.models import User
from django.db import models
class Card(models.Model):
owner = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
serializers.py:
from rest_framework import serializers
from . import models
class CardSerializer(serializers.ModelSerializer):
owner = serializers.StringRelatedField()
class Meta:
model = models.Card
fields = ['owner', 'id']
views.py:
from rest_framework import viewsets
from . import models, serializers
class ListCardsPerUser(viewsets.ModelViewSet):
serializer_class = serializers.CardListSerializer
def get_queryset(self):
models.CardList.objects.filter(owner__id=self.kwargs['user_id'])
urls.py:
from django.urls import path, include
from rest_framework import routers
from . import views
router = routers.SimpleRouter()
router.register(r'cards/by-user-id/<int:user_id>/', views.ListCardsPerUser, basename='cards_list')
urlpatterns = [
path('', include(router.urls)),
]
I'm starting to wonder if it is even possible with routers...
Django version: 4.1 and DRF: 3.14
CodePudding user response:
you should just edit your user serializer
class CardASerializer(serializers.ModelSerializer):
class Meta:
model = Card
fields = "__all__"
class UserSerializer(serializers.ModelSerializer):
cards = CardASerializer(many=True)
class Meta:
model = User
fields = "__all__"
Note that the cards is related_name
class Card(models.Model):
owner = models.ForeignKey(User, null=True,related_name="cards", on_delete=models.SET_NULL)