Django Custom Group Model is a package that allows you to replace the default Django Group model with a custom one with full compatibility with the Django permissions framework.
Here are some reasons why you may want to use this package:
-
Add more fields to the Django Group model
-
Override existing Django Group model fields
-
Rename the Group model to something else
-
When starting a project, setting a custom Group model will allow you to customize it in the future when the need arises.
-
Python: 3.6+
-
Django: 5.0, 4.2, 4.1, 4.0, 3.2, 3.1, 3.0
Install using pip:
pip install django-group-model
Add 'django_group_model'
to your INSTALLED_APPS
. Make sure to place it after the default Django apps (if any) and before any custom apps that define the Group
or User
models.
INSTALLED_APPS = [
...
'django.contrib.staticfiles',
'django_group_model', # Add this
...
]
django-group-model
allows overriding the Group
model by setting the AUTH_GROUP_MODEL
setting to a value that references a custom model.
AUTH_GROUP_MODEL = 'myapp.Group'
The below model is identical to the default Group
model from django.contrib.auth.models
, but allows customizing in the future.
from django_group_model.models import AbstractGroup
class Group(AbstractGroup):
# You can add custom fields here
pass
Here, the name of the class being Group
is important. See below on how to customize the name of the model. In order to use this, set the AUTH_GROUP_MODEL
setting in your settings.py
to point to your custom Group
model.
In your custom User
model (see Customizing authentication in Django), set a field to point to your custom Group
model
...
class User(AbstractUser, ...):
...
groups = models.ManyToManyField(
'myapp.Group',
verbose_name=_("groups"),
blank=True,
help_text=_(
"The groups this user belongs to. A user will get all permissions "
"granted to each of their groups."
),
related_name="user_set",
related_query_name="user",
)
...
Once again, the name of the field is important. See below on how to customize the name of the model. Also take note of the related_name
and related_query_name
. Most of the time, the pattern shown above should work. For a deeper understanding see Django docs here.
Since the name of the new model is Group
, when accessing Groups attached to a permission, you will have to use the custom_group_set
accessor.
permisssion = Permisssion.objects.first()
groups = permission.custom_group_set.all()
This only applies if your custom model is called Group
. If you name it something else (see below). It will use Django's default conventions for the reverse accessor.
Overriding the default Group
model with a custom name involves 2 steps:
-
Create a model class that extends
AbstractGroup
with any name that you like. -
Override
verbose_name
andverbose_name_plural
attributes of theMeta
class.
Let's go through this with an example. We'll override the default Group
model with a model called Role
in this example. But you could call it whatever you like.
First we will create a Role
model that extends AbstractUser
from django_group_model.models import AbstractGroup
class Role(AbstractGroup):
# You can add custom fields here
class Meta:
verbose_name = "role"
verbose_name_plual = "roles"
Next, we'll use it in our user class.
...
class User(AbstractUser, ...):
...
roles = models.ManyToManyField(
'myapp.Role',
blank=True,
related_name="user_set",
related_query_name="user",
)
groups = None
...
IMPORTANT: The name of the field must be the name of your custom model in lowercase + 's'. So, the Role
model becomes roles
. This is a limitation at this point. Feel free to open an issue and a pull request with ideas to resolve this (see the contributing section below).
Note: Here we are setting the groups
to None
which is important to remove the default linking to the default group model in order to avoid conflicts.
Also, take note of the related_name
and related_query_name
. Most of the time, the pattern shown above should work. For a deeper understanding see Django docs here.
Don't forget to set this model as the AUTH_GROUP_MODEL
in settings.py
.
The AbstractGroup
class implements the same attributes as Django's default Group
model.
-
name A unique
CharField
with amax_length
of 150. If you would like to override this field, and you want to call it something else, you must also override the__str__
andnatural_key
methods to return the new field.Example:
class Role(AbstractGroup): name = None new_name = models.CharField(max_length=150, unique=True) # Your other fields def __str__(self): return self.new_name def natural_key(self): return (self.new_name,) class Meta: verbose_name = "role" verbose_name_plual = "roles"
-
permissions A
ManyToManyField
to Django'sPermission
model. You don't want to override this unless you have a very good reason.
We welcome contributions and feedback! If you encounter any issues with the package or have suggestions for improvement, please don't hesitate to open an issue on GitHub.
When opening an issue, please provide as much detail as possible, including steps to reproduce the problem, your environment (Python version, Django version, etc.), and any relevant error messages.
If you'd like to contribute code to this project, you can do so by creating a pull request. We appreciate all contributions, whether it's fixing a bug, implementing a new feature, writing tests, or improving the documentation.
To create a pull request:
-
Fork the repository and create a new branch for your changes.
-
Make your changes, following the project's coding style and conventions.
-
Write tests to cover your changes, if applicable.
-
Ensure that all existing tests pass by running the test suite.
-
Submit a pull request, explaining the changes you've made and why they're valuable.
Thank you for using this package and your interest in contributing to this project! Your contributions help make it better for everyone.