menu

Questions & Answers

Permit creation only if model is subclass of mixin

I would like to allow the creation of a comment only to those models that are sub-classing a specific mixin.

For example, a Post model will have a reverse GenericRelation relation to a Comments model. The comments model is using a custom content types mechanism implemented on top of django's due to the fact that the project uses sharding between multiple databases. The reverse relationship from Post model to Comments is needed to be able to delete Comments when a Post is also deleted.

Putting a simple coding example of what I would like to achieve:

class Post(models.Model, HasCommentsMixin):
some_fields = ....


class HasCommentsMixin(models.Model):
has_comments = GenericRelation('comments.Comment')
class Meta:
    abstract = True

What I would like would me a way to say inside a permission check of a Model: if class is subclass of HasCommentsMixin, allow the creation of a comment. So for the Post model, comments can be created. But if it's not a subclass the Mixin, comments should not be allowed.

I hope I have provided a description that makes sense. I cannot share real code due to product license and protection.

Thank you.

Comments:
2023-01-21 00:55:11
Maybe hasattr(post_instance, 'has_comments') or isinstance( getattr( post_instance, 'has_comments', None), GenericRelation) ?
Answers(1) :

To achieve this, you can use the isinstance() function in combination with the issubclass() function in the permission check to check if the model is a subclass of the HasCommentsMixin.

class IsCommentAllowed(permissions.BasePermission):
    def has_permission(self, request, view):
        model = view.get_queryset().model
        if isinstance(model, HasCommentsMixin) or issubclass(model, HasCommentsMixin):
            return True
        return False
Comments:
2023-01-21 00:55:11
Hi. Thank you for your answer. You mean in the PostViewSet, right? I am wondering if this can be done on the Model layer.
2023-01-21 00:55:11
In that case you might want to try doing something similar in the save method of the Model that inherits the mixin.