TypedPermsModelMixin
A mixin that can be used that adds extended functionality to a Django Model
class. This mixin is a Generic
type, that can take two optional arguments:
- the custom permissions; and
- the default permissions.
These arguments when provided will provide the exact available permissions for that Model. All of the following are valid usecases:
Inheriting with no Generic arguments provided
This will cause that the Model only provide the default Django permissions, they are: "add"
, "change"
, "delete"
, "view"
. Example:
from django.db import models
from django_typed_perms import TypedPermsModelMixin
class Question(TypedPermsModelMixin, models.Model):
...
Inheriting with a single Generic
argument provided
This will cause that the default Django permissions to be present (listed above), plus the ones that you define.
from typing import Annotated, Literal
from django.db import models
from django_typed_perms import TypedPermsModelMixin, get_choices_from_type_hint
QuestionCustomPermsT = Annotated[Literal["publish_question"], "Publish Question"]
class Question(TypedPermsModelMixin[QuestionCustomPermsT], models.Model):
class Meta:
permissions = get_choices_from_type_hint(QuestionCustomPermsT)
Don't forget to add the permissions
to the model's Meta
class
If you forget to add the permissions
to the Meta
class, Django won't create the corresponding Permission
when you run python manage.py makemigrations
. If you forget to add, checking for a permission that doesn't exist will always return a False
value.
What's that Annotated[Literal]
thing that I just saw?
Typing module Annotated
allows you to associate any metadata you want to a specific type. In this case, the Literal
type. With Annotated
you can add as many metadata as you want to a type. But, in this case you're restricted just to a few, they're: str
, a None
value or a gettext_lazy
call.
Literal
is a type that is saying that a value can only be that specific value.
TypedPermsModelMixin
also allows a Union
type of Annotated
types. So if you have more than one custom permission, then you can use the following syntax:
from typing import Annotated, Literal
from django.db import models
from django_typed_perms import TypedPermsModelMixin, get_choices_from_type_hint
QuestionCustomPermsT = (
Annotated[Literal["publish_question"], "Publish Question"]
| Annotated[Literal["clear_votes"], "Clear Votes"]
)
class Question(TypedPermsModelMixin[QuestionCustomPermsT], models.Model):
class Meta:
permissions = get_choices_from_type_hint(QuestionCustomPermsT)
The above sintax is the equivalent of the following syntax:
from typing import Annotated, Literal, Union
from django.db import models
from django_typed_perms import TypedPermsModelMixin, get_choices_from_type_hint
QuestionCustomPermsT = Union[
Annotated[Literal["publish_question"], "Publish Question"],
Annotated[Literal["clear_votes"], "Clear Votes"],
]
class Question(TypedPermsModelMixin[QuestionCustomPermsT], models.Model):
class Meta:
permissions = get_choices_from_type_hint(QuestionCustomPermsT)
Feel free to use the syntax that you like the most.
Inheriting with 2 Generic
arguments provided
If you need to add custom permissions and also override the default permissions, then you can use the following syntax. For example, if you only want the Question
model to have the add
permission, you can:
from typing import Annotated, Literal
from django.db import models
from django_typed_perms import TypedPermsModelMixin, get_choices_from_type_hint
QuestionCustomPermsT = (
Annotated[Literal["publish_question"], "Publish Question"]
| Annotated[Literal["clear_votes"], "Clear Votes"]
)
QuestionDefaultPermsT = (
Annotated[Literal["add"], "Add Question"]
)
class Question(TypedPermsModelMixin[QuestionCustomPermsT, QuestionDefaultPermsT], models.Model):
class Meta:
permissions = get_choices_from_type_hint(QuestionCustomPermsT)
default_permissions = get_choices_from_type_hint(QuestionDefaultPermsT)
Now the only 3 available permissions are: publish_question
, clear_votes
, and add
.