Add basic forum functions

This commit is contained in:
Nathan Chapman 2022-07-19 15:42:10 -06:00
parent dc1ffcad75
commit 70d6398863
12 changed files with 154 additions and 19 deletions

View File

@ -19,8 +19,11 @@ class Topic(models.Model):
"""
name = models.CharField(max_length=255)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('core:tag-detail', kwargs={'pk': self.pk})
return reverse('core:tag-detail', kwargs={'topic_pk': self.pk})
class Tag(models.Model):
@ -118,7 +121,10 @@ class Post(models.Model):
objects = PostManager()
def get_absolute_url(self):
return reverse('core:post-detail', kwargs={'pk': self.pk})
return reverse('core:post-detail', kwargs={
'topic_pk': self.topic.pk,
'post_pk': self.pk
})
class Meta:
ordering = ['-pub_date']

View File

@ -0,0 +1,13 @@
{% extends 'base.html' %}
{% block content %}
<h1>Delete comments</h1>
<form method="POST" action="{% url 'core:comment-delete' comment.pk %}">
{% csrf_token %}
<p>Are you sure you want to delete "{{ comments }}"?</p>
{{ form.as_p }}
<p>
<input type="submit" value="Delete"> or <a href="{% url 'core:comment-detail' comment.pk %}">cancel</a>
</p>
</form>
{% endblock %}

View File

@ -0,0 +1,12 @@
{% extends 'base.html' %}
{% block content %}
<h1>+ New comments</h1>
<form method="POST" action="{% url 'core:comment-create' %}">
{% csrf_token %}
{{ form.as_p }}
<p>
<input type="submit" value="Create"> or <a href="{% url 'core:comment-list' %}">cancel</a>
</p>
</form>
{% endblock %}

View File

@ -0,0 +1,12 @@
{% load helpers %}
<figure class="comment">
<figcaption>
<span class="comment__author">{{ comment.author }}</span><br>
<time>{{ comment.created_at }}</time>
</figcaption>
<div>
{{ comment.content|markdown|safe }}
</div>
<div class="comment__options">&hellip;</div>
</figure>

View File

@ -0,0 +1,13 @@
{% extends 'base.html' %}
{% block content %}
<h1>Update comment</h1>
<p><a href="{% url 'core:commend-delete' comment.pk %}">Delete</a></p>
<form method="POST" action="{% url 'core:comment-update' comment.pk %}">
{% csrf_token %}
{{ form.as_p }}
<p>
<input type="submit" value="Save changes"> or <a href="{% url 'core:comment-detail' comment.pk %}">cancel</a>
</p>
</form>
{% endblock %}

View File

@ -0,0 +1,19 @@
{% extends 'base.html' %}
{% block content %}
<h1>Comments</h1>
<p>
<a href="{% url 'core:comment-create' %}">+ New comment</a>
</p>
<table>
<tbody>
{% for comment in comments_list %}
<tr>
<dt>{{ comment }}</dt>
</tr>
{% empty %}
<tr>No comments yet.</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -2,11 +2,11 @@
{% block content %}
<h1>+ New Post</h1>
<form method="POST" action="{% url 'post-create' %}" enctype="multipart/form-data">
<form method="POST" action="{% url 'core:post-create' topic.pk %}" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<p>
<input type="submit" value="Create"> or <a href="{% url 'post-list' %}">cancel</a>
<input type="submit" value="Create"> or <a href="{% url 'core:post-list' topic.pk %}">cancel</a>
</p>
</form>
{% endblock %}

View File

@ -1,6 +1,11 @@
{% extends 'base.html' %}
{% load static %}
{% load helpers %}
{% block head %}
<script type="module" src="{% static 'scripts/comments.js' %}" defer></script>
{% endblock head %}
{% block content %}
<article class="post">
<header>
@ -9,12 +14,31 @@
</figure>
<h1>{{ post.title }}</h1>
<p>
<a href="{% url 'post-update' post.pk %}">Edit</a>
<a href="{% url 'post-delete' post.pk %}">Delete</a>
<a href="{% url 'core:post-update' post.topic.pk post.pk %}">Edit</a>
<a href="{% url 'core:post-delete' post.topic.pk post.pk %}">Delete</a>
</p>
</header>
<section class="post__content">
{{ post.content|markdown|safe }}
</section>
<section class="comments detail__comments">
<h2>Discussion</h2>
<div class="comments__list">
{% for comment in post.comments.all %}
{% include 'core/comment_detail.html' with comment=comment %}
<hr>
{% endfor %}
</div>
<div class="comments__form">
<h3>Add a comment</h3>
<form action="{% url 'core:comment-create' %}" method="POST">
{% csrf_token %}
{{ comment_create_form.as_p }}
<input class="action-button" type="submit" value="Post comment">
</form>
</div>
</section>
</article>
{% endblock %}

View File

@ -7,4 +7,13 @@
<a href="{% url 'core:topic-delete' topic.pk %}">Delete</a>
</p>
<p>{{ topic }}</p>
<section>
<a href="{% url 'core:post-create' topic.pk %}">+ New post</a>
{% for post in topic.post_list.all %}
<h3><a href="{% url 'core:post-detail' topic.pk post.pk %}">{{ post.title }}</a></h3>
{% empty %}
<p>No posts</p>
{% endfor %}
</section>
{% endblock %}

View File

@ -1,17 +1,22 @@
{% extends 'base.html' %}
{% block content %}
<h1>Topics</h1>
<a href="{% url 'core:topic-create' %}">+ New topic</a>
<table>
<tbody>
<article>
<h1>Topics</h1>
<a href="{% url 'core:topic-create' %}">+ New topic</a>
<section>
{% for topic in topic_list %}
<tr>
<dt>{{ topic }}</dt>
</tr>
<h3><a href="{% url 'core:topic-detail' topic.pk %}">{{ topic.name }}</a></h3>
<ul>
{% for post in topic.post_list.all %}
<li><a href="{% url 'core:post-detail' topic.pk post.pk %}">{{ post.title }}</a></li>
{% empty %}
<li>No posts yet</li>
{% endfor %}
</ul>
{% empty %}
<tr>No topics yet.</tr>
<p>No topics yet.</p>
{% endfor %}
</tbody>
</table>
</section>
</article>
{% endblock %}

View File

@ -42,11 +42,11 @@ urlpatterns = [
name='topic-list'
),
path(
'new/',
'topics/new/',
views.TopicCreateView.as_view(),
name='topic-create'
),
path('<int:pk>/', include([
path('topics/<int:topic_pk>/', include([
path(
'',
views.TopicDetailView.as_view(),
@ -75,7 +75,7 @@ urlpatterns = [
views.PostCreateView.as_view(),
name='post-create'
),
path('<int:pk>/', include([
path('<int:post_pk>/', include([
path(
'',
views.PostDetailView.as_view(),

View File

@ -9,6 +9,7 @@ from django.views.generic.edit import (
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.contrib.contenttypes.models import ContentType
from .models import Topic, Post, Comment
from .forms import PostForm, CommentCreateForm
@ -60,16 +61,19 @@ class TopicCreateView(SuccessMessageMixin, CreateView):
class TopicDetailView(DetailView):
model = Topic
pk_url_kwarg = 'topic_pk'
class TopicUpdateView(SuccessMessageMixin, UpdateView):
model = Topic
pk_url_kwarg = 'topic_pk'
success_message = 'Topic saved.'
fields = '__all__'
class TopicDeleteView(SuccessMessageMixin, DeleteView):
model = Topic
pk_url_kwarg = 'topic_pk'
success_message = 'Topic deleted.'
success_url = reverse_lazy('topic-list')
@ -84,18 +88,36 @@ class PostCreateView(SuccessMessageMixin, CreateView):
template_name_suffix = '_create_form'
fields = '__all__'
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['topic'] = get_object_or_404(Topic, pk=self.kwargs['topic_pk'])
return context
class PostDetailView(DetailView):
model = Post
pk_url_kwarg = 'post_pk'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
object_content_type = ContentType.objects.get_for_model(self.object).pk
context['comment_create_form'] = CommentCreateForm(initial={
'content_type': object_content_type,
'object_id': self.object.pk
})
return context
class PostUpdateView(SuccessMessageMixin, UpdateView):
model = Post
pk_url_kwarg = 'post_pk'
success_message = 'Post saved.'
fields = '__all__'
class PostDeleteView(SuccessMessageMixin, DeleteView):
model = Post
pk_url_kwarg = 'post_pk'
success_message = 'Post deleted.'
success_url = reverse_lazy('article-list')