Reputation: 170
In my ModelViewSet, I am trying to exclude my tenant field to prevent users from seeing the tenant id (from django-simple-multitenant). However, I am not able to develop a generic ModelSerializer because I am always required to define the model Meta in the ModelSerializer class. My source code that works (non-generic) is below. I would like to achieve either one of the options below:
Serializer works by picking up actual class model without need to specify the model in Meta class of the serializer
Set my Serializer in DEFAULT_MODEL_SERIALIZER_CLASS, and have it work (again without specifying the model in the Meta class of the serializer
It works well below, but when I assign the Serializer in DEFAULT_MODEL_SERIALIZER_CLASS, it does not seem to work.
class ExcludeTenantSerializer(serializers.ModelSerializer):
class Meta:
model = Product
exclude = ('tenant', )
class ProductViewSet(viewsets.ModelViewSet):
model = Product
ordering = ('id', )
serializer_class = ExcludeTenantSerializer
def get_queryset(self):
tenant = get_current_tenant()
if tenant:
return self.model.objects.filter(tenant=tenant)
else:
return self.model.objects.none()
Upvotes: 4
Views: 2267
Reputation: 170
I have found a way to do this. It is to dynamically create a class in the get_serializer_class function. To make this generic, I wrote a class that extends from ModelViewSet, and have all the multi-tenant aware classes that I will expose through Django REST Framework to subclass it.
class TenantViewSet(viewsets.ModelViewSet):
def __init__(self, **kwargs):
self.serializer_class = None
super(TenantViewSet, self).__init__(**kwargs)
def get_serializer_class(self):
if self.serializer_class is not None:
return self.serializer_class
class ExcludeTenantSerializer(serializers.ModelSerializer):
class Meta:
model = self.model
exclude = ('tenant', )
self.serializer_class = ExcludeTenantSerializer
return self.serializer_class
def get_queryset(self):
tenant = get_current_tenant()
if tenant:
return self.model.objects.filter(tenant=tenant)
else:
return self.model.objects.none()
Upvotes: 5