Just need some help getting over a wall I've hit.
I have a web application that whenever a user signs up, is assigned a License. This License has CustomPermissions attached to it telling what values of a field within a materialized view they have access to. I have an API that needs to filter data requested against the User who requested it based on the User's license. I drafted some example models below that outlines my problem.
class CustomPermission(models.Model):
name = models.CharField(max_length=255)
field = models.CharField(max_length=255)
value = models.CharField(max_length=255)
class License(models.Model):
name = models.CharField(max_length=255)
permissions = models.ManyToManyField(CustomPermissions)
...
class User(AbstractBaseUser):
license = models.ForeignKey(License, on_delete=models.CASCADE)
...
This works fine if I'm only filtering columns with text values. I can just do
...
user = request.user
permissions = user.license.permissions.values_list('field', 'value')
return queryset.objects.filter(**{field: value for field, value in permissions})
This issue is that I cannot filter against other datatypes (datetimes for example). If I wanted to limit access to data published in the last 90 days for example, there's no way to represent that in this model.
To solve this I was thinking of using a sparse table for the CustomPermission model. Something like
class CustomPermission(models.Model):
name = models.CharField(max_length=255)
field = models.CharField(max_length=255)
operation = models.CharField(max_length='32')
text_value = models.CharField(max_length=255, null=True, blank=True)
date_value = models.DateField(null=True, blank=True)
Where operation would be equal to '__gt', '__lt', ... things like that. I can then just do something similar as before
...
user = request.user
permissions = user.license.permissions.values_list('field', 'operation', 'text_value', 'date_value')
return queryset.objects.filter(**{fld + op: txt_val or dat_val for fld, op, txt_val, dat_val in permissions})
But this does not feel right, and can get messy quickly. Any suggestions?