Skip to main content

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:

  1. self.set_add_comment_url(self.pk)
  2. def add_comment_func(cls, request, pk: int):
  3. target = cls.objects.get(pk=pk)
  4. 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

django-add-comments-0.0.7.tar.gz (47.8 kB view details)

Uploaded Source

Built Distribution

django_add_comments-0.0.7-py3-none-any.whl (50.3 kB view details)

Uploaded Python 3

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

Hashes for django-add-comments-0.0.7.tar.gz
Algorithm Hash digest
SHA256 fbcbb30e2094fb7d614e9a7fd31fa6d4953f59bf14e9f1bade5c7478ad9ea01b
MD5 6e72cf1315395ac328f61e6cf9c13140
BLAKE2b-256 46b7d64028bb17953f3b07b24cafae0e73b682d8084a6b725f56520a8a20e173

See more details on using hashes here.

File details

Details for the file django_add_comments-0.0.7-py3-none-any.whl.

File metadata

File hashes

Hashes for django_add_comments-0.0.7-py3-none-any.whl
Algorithm Hash digest
SHA256 ef1b5cfbc817df162c54aa9ab8bee42691ce32b564f99704856557c65420f347
MD5 499938b44cdbf6151a940ec8ff698a35
BLAKE2b-256 3978c3aa4869fcafbbdbebbbdb5ebb71c3eafc803bc571ab95cea5e268493eb6

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page