After a lot of debugging, I found the issue!
This code did not work as intended because LoggedModelManager.__init__
fails when provided no parameters.
I made the assumption that mycustom manager is only instantiated when my model B is defined:
class B(models.Model):
objects = LoggedModelManager(logging_model='BLog') # I thought this was the only place the constructor was called.
However, this is not the case. When resolving related model sets, the ModelSerializer
class from the Django Rest Framework library will instantiate a manager for the related model. This instantiation is done with none of the parameters I expected, therefore an exception was raised and the related set ignored. Sadly, this error is not reported by the serializer, making it very hard to debug.
Make sure your custom manager can be instantiated at a later time with no parameters. I did this by returning the default QuerySet
if this was the case:
# Defining the Manager
class LoggedModelManager(models.Manager):
# Save the name of the logging model, which are `ALog` and `BLog` in our example.
def __init__(self, *args, **kwargs):
if 'logging_model' in kwargs:
logging_model = kwargs.pop('logging_model')
self.logging_model_name = logging_model.lower()
else:
self.logging_model_name = None
super().__init__(*args, **kwargs)
# Here we filter out the logs from the logged instances.
def get_queryset(self) -> models.QuerySet:
if self.logging_model_name is None:
return super().get_queryset()
return super().get_queryset().filter(**{self.logging_model_name+"__isnull": True})
Hope this was helpful! I wonder if this is worth a ticket to ensure the Django Rest Framework serializers actually raise an error instead of silencing it.