Add and display htmx comments to arbitrary Django models.
Project description
django-add-comments
Add comments
to a Django model via mixin:
# app/models.py
from comment.models import AbstractCommentable # import mixin
class Sentinel(AbstractCommentable): # add to class declaration
"""Any `app`, e.g. `essay`, `article`... can be 'commentable'."""
title = models.CharField(max_length=50)
Action | Authorization | Description |
---|---|---|
View comments list | All users | Add filter public/private later |
Get comment form | Authenticated users | Reactive via htmx / hyperscript [^1] |
Delete / edit comment | Authorized authors | Reactive via htmx / hyperscript [^1] |
Setup
Load virtual env
.venv> poetry add django-add-comments # pip3 install django-add-comments
Will include dependencies from pyproject.toml:
python = "^3.8"
Django = "^4.0"
django-extensions = "^3.1.5"
django-crispy-forms = "^1.13.0"
Add app to project settings
# in project_folder/settings.py
INSTALLED_APPS = [
...,
'crispy_forms', # add crispy_forms at least > v1.13, if not yet added
'comments' # this is the new django-comments folder
]
Add basic routes to urlpatterns
# in project_folder/urls.py
from django.urls import path, include # new
urlpatterns = [
...,
path('comments/', include('comments.urls')) # routes for update, delete, view, toggle comment
]
Add Comment model to database
.venv> python manage.py migrate
Configuration
What we're going to do
>>> obj = Sentinel.objects.create(title="A sample title") # instance is made, e.g. id=1, id=2, etc.
>>> obj.add_comment_url # url to add a comment to `A sample title`
A sentinel is the model being commented on.
We've created a dummy Sentinel
model to represent this construct.
Let's say we've initialized one model instance called obj
with slug
="a-sample-title".
What we'd like is the ability to write a comment to obj
through a url represented by: obj.add_comment_url
@add_comment_url
thus needs to become a property of the Sentinel
model.
Add imports
# sentinels/models.py
from comments.models import AbstractCommentable # new
from django.template.response import TemplateResponse # new
from django.urls import reverse, URLPattern # new
from django.utils.functional import cached_property, classproperty # new
Make sentinel model inherit from abstract base model
# sentinels/models.py
class Sentinel(AbstractCommentable): # new
...
Add model properties
# sentinels/models.py
class Sentinel(AbstractCommentable):
id = models.UUIDField ... # identifier is UUID
slug = models.Slugfield ...
@cached_property # copy this to the sentinel model, note `slug` as identifier
def add_comment_url(self) -> str:
return self.set_add_comment_url(self.slug)
@classmethod # copy this to the sentinel model, note `slug` as identifier
def add_comment_func(cls, request, slug: str) -> TemplateResponse:
target = cls.objects.get(slug=slug)
return cls.allow_commenting_form_on_target_instance(request, target)
@classproperty # copy this to the sentinel model, note `slug` as identifier
def add_comment_path(cls) -> URLPattern:
return cls.set_add_comment_path("<slug:slug>", cls.add_comment_func)
Gotcha: if pk
is identifier, revise <slug:slug>
to <pk:int>
above:
self.set_add_comment_url(self.pk)
def add_comment_func(cls, request, pk: int):
target = cls.objects.get(pk=pk)
cls.set_add_comment_path("<int:pk>", cls.add_comment_func)
Add sentinel namespaced url for adding comments
Add path to the sentinel's url patterns:
# sentinels/urls.py
from .models import Sentinel
from .apps import SentinelConfig # already pre-made during `python manage.py startapp sentinels`
app_name = SentinelConfig.name # remember the `app_name` in relation to the `add_comment_url` property
url_patterns = [
Sentinel.add_comment_path, # This is really just a shortcut to a created path.
...
]
Add template tag for displaying comment form with list of added comments
Add template tag to sentinel's template to show form with list
<!-- sentinels/templates/sentinel_detail.html -->
<h1>Title: {{ object.title }}</h1>
{% load comments %} <!-- see templatetags/comments.py which contains `object.add_comment_url` -->
{% list_comments sentinel_target_obj=object head_label='Add an Answer'%}
<!-- the `object` is whatever variable passed to the template, the head_label provides an ability to label the items to be inputted. The default is 'Add a Comment' -->
The form that represents this "add comment" action / url will be loaded in every comment list. See context in template tag.
[^1]: No page refresh
Project details
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
File details
Details for the file django-add-comments-0.0.7.tar.gz
.
File metadata
- Download URL: django-add-comments-0.0.7.tar.gz
- Upload date:
- Size: 47.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.2.0a2 CPython/3.10.2 Darwin/21.2.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | fbcbb30e2094fb7d614e9a7fd31fa6d4953f59bf14e9f1bade5c7478ad9ea01b |
|
MD5 | 6e72cf1315395ac328f61e6cf9c13140 |
|
BLAKE2b-256 | 46b7d64028bb17953f3b07b24cafae0e73b682d8084a6b725f56520a8a20e173 |
File details
Details for the file django_add_comments-0.0.7-py3-none-any.whl
.
File metadata
- Download URL: django_add_comments-0.0.7-py3-none-any.whl
- Upload date:
- Size: 50.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.2.0a2 CPython/3.10.2 Darwin/21.2.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ef1b5cfbc817df162c54aa9ab8bee42691ce32b564f99704856557c65420f347 |
|
MD5 | 499938b44cdbf6151a940ec8ff698a35 |
|
BLAKE2b-256 | 3978c3aa4869fcafbbdbebbbdb5ebb71c3eafc803bc571ab95cea5e268493eb6 |