Add basic forum functions
This commit is contained in:
parent
dc1ffcad75
commit
70d6398863
@ -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']
|
||||
|
||||
13
src/core/templates/core/comment_confirm_delete.html
Normal file
13
src/core/templates/core/comment_confirm_delete.html
Normal 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 %}
|
||||
12
src/core/templates/core/comment_create_form.html
Normal file
12
src/core/templates/core/comment_create_form.html
Normal 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 %}
|
||||
12
src/core/templates/core/comment_detail.html
Normal file
12
src/core/templates/core/comment_detail.html
Normal 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">…</div>
|
||||
</figure>
|
||||
13
src/core/templates/core/comment_form.html
Normal file
13
src/core/templates/core/comment_form.html
Normal 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 %}
|
||||
19
src/core/templates/core/comment_list.html
Normal file
19
src/core/templates/core/comment_list.html
Normal 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 %}
|
||||
@ -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 %}
|
||||
|
||||
@ -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 %}
|
||||
|
||||
@ -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 %}
|
||||
|
||||
@ -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 %}
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user