Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/justmars/django-add-comments
Add and display htmx comments to arbitrary Django models.
https://github.com/justmars/django-add-comments
Last synced: 3 days ago
JSON representation
Add and display htmx comments to arbitrary Django models.
- Host: GitHub
- URL: https://github.com/justmars/django-add-comments
- Owner: justmars
- License: bsd-3-clause
- Created: 2021-12-05T05:09:56.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2023-05-16T16:56:15.000Z (over 1 year ago)
- Last Synced: 2024-10-07T22:11:00.077Z (about 1 month ago)
- Language: Python
- Size: 149 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# django-add-comments
Add `comments` to a Django model via mixin:
```python
# app/models.py
from comment.models import AbstractCommentable # import mixinclass 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
```zsh
.venv> poetry add django-add-comments # pip3 install django-add-comments
```Will include dependencies from [pyproject.toml](../../pyproject.toml):
```toml
python = "^3.8"
Django = "^4.0"
django-extensions = "^3.1.5"
django-crispy-forms = "^1.13.0"
```### Add app to project settings
```python
# 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
```python
# in project_folder/urls.py
from django.urls import path, include # newurlpatterns = [
...,
path(
"comments/", include("comments.urls")
), # routes for update, delete, view, toggle comment
]
```### Add Comment model to database
```zsh
.venv> python manage.py migrate
```## Configuration
### What we're going to do
```zsh
>>> 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
```python
# 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
```python
# sentinels/models.py
class Sentinel(AbstractCommentable): # new
...
```### Add model properties
```python
# sentinels/models.py
class Sentinel(AbstractCommentable):
id = models.UUIDField
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("", cls.add_comment_func)
```_Gotcha_: if `pk` is identifier, revise `` to `` 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("", cls.add_comment_func)`### Add sentinel namespaced url for adding comments
Add path to the sentinel's url patterns:
```python
# 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
```jinja
Title: {{ object.title }}
{% load comments %}
{% list_comments sentinel_target_obj=object head_label='Add an Answer'%}```
The form that represents this "add comment" action / url will be loaded in every comment list. See context in [template tag](./comments/templatetags/comments.py).
[^1]: [No page refresh](./comments/docs/frontend.md)