Hey Django community,
I have a question regarding creating a new Django package that others can install and use. My company is getting off Salesforce and my team and I are in the process of creating a Django-based CRM as a replacement. One feature that I built out is field-level permissions, very similar to that of Salesforce.
Essentially how it works is I have a custom FieldPermission model and ManyToMany fields on User and Group for field permission assignment. This feature uses the Django model meta API to find fields within the app’s models and automatically create field permission records for them, which can then be assigned out to users and groups. By using a custom template tag, each field in the templates can check a user’s permission on the field level for both read and edit (may build out more in the future) .With some caching and optimizations like prefetch_related, it actually works really well and I’m pleased with the result.
Prior to building this out, I looked around for existing Django packages by way of Google, AI, and websites like https://djangopackages.org/, but nothing quite fit the bill. I’m aware of packages like django-guardian, django-rules, and django-role-permissions and while these are exceedingly useful contributions, they didn’t quite match the use-case. This leads me to where I am now where I’m wondering if the community would find a reusable field-level permissions app like this useful in their projects.
The issue is I haven’t the faintest clue how to even begin contributing to the Django ecosystem, let alone creating a package that people may find useful. But I want to learn and the first step is asking people smarter than me.
So, Django community, if any of you have ever created a Django package, please share any insight you have here, especially with getting started! I’d love to chat and hear your thoughts.
Thanks!
-Eddie Mapes
Hi, I have created three django packages (django-admin-action-forms, django-no-queryset-admin-actions, django-extended-makemessages) and although they are nowhere as popular as the top used ones, I learned a lot.
For the most part, a django package is an app, that could be copy-pasted to any project, and most of them are added to project by adding them in INSTALLED_APPS
in settings.
So, I would suggest separating all the logic related to field based permissions into a single app e.g. django-model-field-permissions
. When you do that, converting it into a pip installable package is quite easy. You have a few options, you can manually push package version to PyPI (as i do in my packages), or use newer so called Trusted Publishers, both ways have their pros and cons.
A few tips for creating a Django package:
- name it with
django-...
prefix
- use
-
in package name e.g. django-model-field-permissions
, but use _
in app folder name e.g. django_model_field_permissions
, do not use different name for package and folder, it often makes it very confusing
- import commonly used parts of the package in
__init__.py
, noone wants to add several lines of imports from multiple submodules
- stick to Django naming conventions as close as possible, it makes it easier to use the package and understand what is happening
- type your code, it is very important for packages, even more than you own code, avoid
Any
or List
, instead use e.g. "list[int]"
or "QuerySet[User]"
, remember to wrap such types in quotes, as older Python version will not recognize this syntax, don’t be aftaid of types like dict[str, list[tuple[int, str]]]
etc., IDEs will do the work when iterating and will infer the correct type
- split code into multiple files (if necessary), use names as in any django app like
admin.py
or models.py
- avoid dependencies if possible
- preferably make your package work on Django 3.2.x-5.x.x or at least 4.x.x-5.x.x
- think before making a migration, a package should not contain multiple migrations that adds a field, then removes it, then adds it again and renames it, in short, add a squashed migrations, when your work is ready
- create a easy to understand documentation with examples, not many people will use a package, without knowing what it does, and without examples, one would have to read package code to understand how to use it
That is all that I can think of for now, maybe I will recall something more later.
BTW I like the idea for the package, I can think of several usages in projects I manage.
2 Likes
This is super insightful, I appreciate you sharing!
I struggled to find my way doing this kind of thing but I recently changed my packages to use the src
layout which seems a good idea. See Python packaging: use the "src" and Testing & Packaging .
if you’re not already, use tox
to test on combinations of Python versions and Django versions (I think there might be alternative tools, but I don’t know anything about them).
Have a well formatted changelog. Keep a Changelog