feat: allow deleting of posts

This commit is contained in:
m5ka 2024-03-27 16:19:10 +00:00
parent 2fed369027
commit ad27fdf1c2
7 changed files with 63 additions and 9 deletions

View file

@ -5,7 +5,7 @@ from django.urls import include, path
from moku.views.auth import LoginView, LogoutView
from moku.views.blog import IndexBlogView
from moku.views.post import EditPostview, FeedView
from moku.views.post import DeletePostView, EditPostview, FeedView
from moku.views.recipe import (
DeleteRecipeView,
DeleteStepView,
@ -34,7 +34,8 @@ urlpatterns = [
path("blog", IndexBlogView.as_view(), name="blog.index"),
path("privacy", PrivacyView.as_view(), name="privacy"),
path("terms", TermsView.as_view(), name="terms"),
path("edit/<str:uuid>", EditPostview.as_view(), name="post.edit"),
path("post/<str:uuid>", EditPostview.as_view(), name="post.edit"),
path("post/<str:uuid>/delete", DeletePostView.as_view(), name="post.delete"),
path("user/<str:username>", ProfileView.as_view(), name="profile"),
path("user/<str:username>/json", UserJSONView.as_view(), name="json"),
path("recipes", IndexRecipeView.as_view(), name="recipe.index"),

View file

@ -1,9 +1,13 @@
from django.forms import ModelForm
from django.forms import Form, ModelForm
from django.utils.translation import gettext_lazy as _
from moku.models import Post
class DeletePostForm(Form):
pass
class PostForm(ModelForm):
"""Form for creating and updating posts."""

View file

@ -86,10 +86,10 @@ class Post(models.Model):
objects = PostManager()
def __str__(self):
return f"{self.text} on {self.created_at}"
return f"{self.plain_text} on {self.created_at}"
@property
def text(self):
def html(self):
"""
The text of the post, with the post's chosen verb hydrated with food and user
information.
@ -101,3 +101,11 @@ class Post(models.Model):
),
"food": escape(self.food),
}
@property
def plain_text(self):
"""The text of the post as plain text."""
return self.get_verb_display() % {
"user": f"@{self.created_by.username}",
"food": escape(self.food),
}

View file

@ -2,7 +2,16 @@
{% block content %}
<div class="content block">
<h2>{% trans time_ago=post.created_at|naturaltime %}editing post from {{ time_ago }}{% endtrans %}</h2>
<p class="mb">
👈 <a href="{{ url('feed') }}">back to feed</a>
<span class="mx">•</span>
❌ <a href="{{ url('post.delete', uuid=post.uuid) }}">delete post</a>
</p>
<h2>
{% trans post_text=post.plain_text, time_ago=post.created_at|naturaltime %}
editing {{ post_text }} from {{ time_ago }}
{% endtrans %}
</h2>
{% include "moku/snippets/post_form.jinja" %}
</div>
{% endblock content %}

View file

@ -8,7 +8,7 @@
{% endif %}
<div class="emoji">{{ post.emoji }}</div>
<div class="body">
<p class="food user-content">{{ post.text|safe }}</p>
<p class="food user-content">{{ post.html|safe }}</p>
<p class="metadata">
{{ post.created_at|naturaltime }}
{% if request.user.is_authenticated and request.user.id == post.created_by.id %}

View file

@ -12,4 +12,5 @@ def test_post(post: Post, re_uuid: re.Pattern):
assert post.pk > 0
assert post.pk == post.id
assert re_uuid.match(post.uuid) is not None
assert post.text == '<a href="/user/jean">@jean</a> cooked sausage surprise'
assert post.html == '<a href="/user/jean">@jean</a> cooked sausage surprise'
assert post.plain_text == "@jean cooked sausage surprise"

View file

@ -1,12 +1,14 @@
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.humanize.templatetags.humanize import naturaltime
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.translation import gettext as _
from moku.constants import EMOJI_CATEGORIES, Verbs
from moku.forms.post import PostForm
from moku.forms.post import DeletePostForm, PostForm
from moku.images import process_post_image
from moku.models.post import Post
from moku.models.recipe import Recipe
@ -20,6 +22,35 @@ def _get_verbs(username):
)
class DeletePostView(LoginRequiredMixin, UserPassesTestMixin, FormView):
"""Allows users to delete their previous posts."""
template_name = "moku/delete.jinja"
form_class = DeletePostForm
def form_valid(self, form):
self.post_object.delete()
messages.success(self.request, _("post deleted successfully!"))
return redirect("feed")
def get_context_data(self, **kwargs):
return {
**super().get_context_data(**kwargs),
"item": _("%(post_text)s from %(time_ago)s") % {
"post_text": self.post_object.plain_text,
"time_ago": naturaltime(self.post_object.created_at),
},
"back_url": reverse("post.edit", kwargs={"uuid": self.post_object.uuid}),
}
@cached_property
def post_object(self):
return get_object_or_404(Post, uuid=self.kwargs.get("uuid"))
def test_func(self):
return self.request.user.id == self.post_object.created_by.id
class EditPostview(LoginRequiredMixin, UserPassesTestMixin, FormView):
"""Allows users to edit their previous posts."""