I have DRF API that supports including the books of an author in an authors
get request.
Our API has a soft delete system where Book(2) marked as deleted.
But when I do the request below Book(2) is still included in the response.
I would like to have only Book(1) in the response of this request.
GET
http://localhost/authors/2?include=books
API returns to me:
{
"data": {
"type": "Author",
"id": "2",
"attributes": {...},
"relationships": {
"books": {
"meta": {
"count": 2
},
"data": [
{
"type": "Book",
"id": "1"
},
{
"type": "Book",
"id": "2"
}
]
}
}
},
"included": [
{
"type": "Book",
"id": "1",
"attributes": {...}
},
{
"type": "Book",
"id": "2",
"attributes": {...}
}
]
}
I have a BaseModel
that handles the soft deletion overriding the delete
method:
class BaseModel(Model):
archive = BoolYesNoField(db_column="archive", default=False, null=False)
created = DateTimeField(db_column="created", auto_now_add=True, null=False)
updated = DateTimeField(db_column="updated", auto_now=True, null=False)
objects = BaseManager()
all_objects = BaseManager(alive_only=False)
def delete(self):
self.archive = True
self.save()
relate_obj_delete(self)
def hard_delete(self):
super(Model, self).delete()
def undelete(self):
self.archive = False
self.save()
Manager
class BaseManager(Manager):
def __init__(self, *args, **kwargs):
self.alive_only = kwargs.pop("alive_only", True)
super(BaseManager, self).__init__(*args, **kwargs)
def get_queryset(self):
if self.alive_only:
return BaseQuerySet(self.model).filter(archive=False)
return BaseQuerySet(self.model)
def hard_delete(self):
return self.get_queryset().hard_delete()
AuthorViewSet
class AuthorViewSet(BaseViewSet):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
filterset_class = AuthorFilterSet
Serializer
class AuthorSerializer(BaseSerializer):
books = ResourceRelatedField(many=True, read_only=True)
included_serializers = {
"books": BookSerializer,
}
class Meta(BaseSerializer.Meta):
model = Author
If someone could just point me out in the right direction I would be really helpful. There is probably a function that I need to override somewhere but I can't seem to find it.
CodePudding user response:
Your issue is in your serializer. By default Django will use Model._base_manager
to fetch related objects and not your custom manager. You need to specify in your nested ResourceRelatedField field which manager you would like to use
class AuthorSerializer(BaseSerializer):
books = ResourceRelatedField(
queryset=Book.objects,
many=True,
read_only=True
)
...