Opinionated collection of Django and DRF tools that came in handy time and again.
Project description
… wait what? no seriously, why isn’t that part of Django/DRF?
Opinionated collection of Django and Django REST framework tools that came in handy time and again.
- AdminItemAction
Allow triggering context-aware custom admin operations in model list views.
- admin_navigation_link
Allow navigation from the admin list view to other related models via links.
- MinimalUser (abstract model)
Bare minimum user model ready for customization.
Removes the username and auxiliary fields like first_name and last_name.
Allow creating users without a valid password (unusable password)
Abstract since its highly recommended to subclass the user model anyway.
- ValidatedJSONField (model field)
validate the structure of JSON fields with Pydantic models.
- TokenAuthentication
When OAuth2 adds too much complexity, DRF’s TokenAuthentication is too simple, and django-rest-knox does not quite fit the permissioning.
No plain passwords in database (PBKDF2, i.e. hashed and salted)
Enabled for permission scoping
Easy (one-time-view) token creation in Django admin
- BaseModel (abstract model)
Reusable base model with automatic created_at, updated_at fields.
Primary key is a random UUID (uuid4).
Ensure validation logic (full_clean()) always runs, not just in a subset of cases.
- AppSettings
A settings container with defaults and string importing inspired by DRF’s APISettings
License
Provided by T. Franzel, Licensed under 3-Clause BSD.
Requirements
Python >= 3.6
Django >= 3.0
Django REST Framework (optional)
Installation
$ pip install django-seriously
Demo
Showcasing AdminItemAction, admin_navigation_link, MinimalUser and TokenAuthentication
Usage
AdminItemAction
# admin.py
from django_seriously.utils.admin import AdminItemAction
class UserAdminAction(AdminItemAction[User]):
model_cls = User
actions = [
("reset_invitation", "Reset Invitation"),
]
@classmethod
def is_actionable(cls, obj: User, action: str) -> bool:
# check whether action should be shown for this item
if action == "reset_invitation":
return is_user_resettable_check(obj) # your code
return False
def perform_action(self, obj: User, action: str) -> Any:
# perform the action on the item
if action == "reset_invitation":
perform_your_resetting(obj) # your code
obj.save()
@admin.register(User)
class UserAdmin(ModelAdmin):
# insert item actions into a list view column
list_display = (..., "admin_actions")
def admin_actions(self, obj: User):
return UserAdminAction.action_markup(obj)
# urls.py
from django_seriously.utils.admin import AdminItemAction
urlpatterns = [
...
# item actions must precede regular admin endpoints
path("admin/", AdminItemAction.urls()),
path("admin/", admin.site.urls),
]
TokenAuthentication
# settings.py
INSTALLED_APPS = [
...
# only required if auth token is not extended by you
'django_seriously.authtoken',
...
]
SERIOUSLY_SETTINGS = {
"AUTH_TOKEN_SCOPES": ["test-scope", "test-scope2"]
}
# views.py
from django_seriously.authtoken.authentication import TokenAuthentication, TokenHasScope
class TestViewSet(viewsets.ModelViewSet):
...
permission_classes = [TokenHasScope]
authentication_classes = [TokenAuthentication]
required_scopes = ['test-scope']
MinimalUser
# models.py
from django_seriously.minimaluser.models import MinimalAbstractUser
from django_seriously.utils.models import BaseModel
# BaseModel is optional but adds useful uuid, created_at, updated_at
class User(BaseModel, MinimalAbstractUser):
pass
# admin.py
from django_seriously.minimaluser.admin import MinimalUserAdmin
@admin.register(User)
class UserAdmin(MinimalUserAdmin):
pass
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for django_seriously-0.4.1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1ab9a212c82fec503edd1576e4c84167068e9878b4138431c5d68518127a84da |
|
MD5 | dde970ad90f3b88b8cfb0033406ff4a0 |
|
BLAKE2b-256 | d1447ef9494bb0c6bb09b797a83acd399034b5c065e1aedf522d99a8bfdc5f27 |