Commit 5a7d79342b098e356e5b6cda9d86764cea3bd8ec
1 parent
df375701
Exists in
master
and in
5 other branches
Adding post edition [Issue: #74]
Showing
8 changed files
with
132 additions
and
57 deletions
Show diff stats
forum/models.py
| ... | ... | @@ -41,6 +41,15 @@ class Post(models.Model): |
| 41 | 41 | def __str__(self): |
| 42 | 42 | return ''.join([self.user.name, " / ", str(self.post_date)]) |
| 43 | 43 | |
| 44 | + def is_modified(self): | |
| 45 | + create = self.post_date.strftime("%Y-%m-%d %H:%M:%S") | |
| 46 | + edit = self.modification_date.strftime("%Y-%m-%d %H:%M:%S") | |
| 47 | + | |
| 48 | + if create != edit: | |
| 49 | + return True | |
| 50 | + | |
| 51 | + return False | |
| 52 | + | |
| 44 | 53 | """ |
| 45 | 54 | It represents an answer to a forum's post |
| 46 | 55 | """ | ... | ... |
forum/static/js/forum.js
| ... | ... | @@ -50,6 +50,54 @@ function showForum(url, forum_id) { |
| 50 | 50 | $('#forumModal').modal(); |
| 51 | 51 | } |
| 52 | 52 | |
| 53 | +/* | |
| 54 | +* | |
| 55 | +* Function to load form to edit post | |
| 56 | +* | |
| 57 | +*/ | |
| 58 | +function edit_post(url, post_id) { | |
| 59 | + $.ajax({ | |
| 60 | + url: url, | |
| 61 | + success: function(data) { | |
| 62 | + $("#post_"+post_id).find(".post_content").hide(); | |
| 63 | + $("#post_"+post_id).find(".post_content").after(data); | |
| 64 | + | |
| 65 | + var frm = $("#post_"+post_id).find(".edit_post_form"); | |
| 66 | + frm.submit(function () { | |
| 67 | + $.ajax({ | |
| 68 | + type: frm.attr('method'), | |
| 69 | + url: frm.attr('action'), | |
| 70 | + data: frm.serialize(), | |
| 71 | + success: function (data) { | |
| 72 | + $("#post_"+post_id).parent().after(data); | |
| 73 | + frm.parent().parent().remove(); | |
| 74 | + }, | |
| 75 | + error: function(data) { | |
| 76 | + console.log(frm.serialize()); | |
| 77 | + console.log('Error'); | |
| 78 | + } | |
| 79 | + }); | |
| 80 | + return false; | |
| 81 | + }); | |
| 82 | + } | |
| 83 | + }); | |
| 84 | +} | |
| 85 | + | |
| 86 | +/* | |
| 87 | +* | |
| 88 | +* Function to cancel post edition | |
| 89 | +* | |
| 90 | +*/ | |
| 91 | +function cancelEditPost(post_id) { | |
| 92 | + $("#post_"+post_id).find(".post_content").show(); | |
| 93 | + $("#post_"+post_id).find(".edit_post_form").remove(); | |
| 94 | +} | |
| 95 | + | |
| 96 | +/* | |
| 97 | +* | |
| 98 | +* Function to delete a post | |
| 99 | +* | |
| 100 | +*/ | |
| 53 | 101 | function delete_post(url, post) { |
| 54 | 102 | var csrftoken = getCookie('csrftoken'); |
| 55 | 103 | |
| ... | ... | @@ -74,36 +122,4 @@ function answer(id, url) { |
| 74 | 122 | }); |
| 75 | 123 | |
| 76 | 124 | $("#post_"+id).find(".answer_post").show(); |
| 77 | -} | |
| 78 | - | |
| 79 | -function showPosts(url, forum) { | |
| 80 | - if ($("#collapse" + forum).hasClass('in')) { | |
| 81 | - $("#collapse" + forum).collapse('hide'); | |
| 82 | - } else { | |
| 83 | - $.ajax({ | |
| 84 | - url: url, | |
| 85 | - data: {'forum': forum}, | |
| 86 | - success: function(data) { | |
| 87 | - $("#collapse" + forum).find(".well").html(data); | |
| 88 | - } | |
| 89 | - }); | |
| 90 | - | |
| 91 | - $("#collapse" + forum).collapse('show'); | |
| 92 | - } | |
| 93 | -} | |
| 94 | - | |
| 95 | -function showPostsAnswers(url, post) { | |
| 96 | - if ($("#collapse" + post).hasClass('in')) { | |
| 97 | - $("#collapse" + post).collapse('hide'); | |
| 98 | - } else { | |
| 99 | - $.ajax({ | |
| 100 | - url: url, | |
| 101 | - data: {'post': post}, | |
| 102 | - success: function(data) { | |
| 103 | - $("#collapse" + post).find(".well").html(data); | |
| 104 | - } | |
| 105 | - }); | |
| 106 | - | |
| 107 | - $("#collapse" + post).collapse('show'); | |
| 108 | - } | |
| 109 | 125 | } |
| 110 | 126 | \ No newline at end of file | ... | ... |
forum/templates/post/post_list.html
| ... | ... | @@ -17,17 +17,24 @@ |
| 17 | 17 | <i class="material-icons">more_horiz</i> |
| 18 | 18 | </a> |
| 19 | 19 | <ul class="dropdown-menu" aria-labelledby="dropdownMenu1"> |
| 20 | - <li><a href="javascript:void(0)"><i class="material-icons">create</i> {% trans 'Edit' %}</a></li> | |
| 20 | + <li><a href="javascript:edit_post('{% url 'forum:update_post' post.id %}', '{{ post.id }}')"><i class="material-icons">create</i> {% trans 'Edit' %}</a></li> | |
| 21 | 21 | <li><a href="javascript:javascript:delete_post('{% url 'forum:delete_post' post.id %}', '{{ post.id }}')"><i class="material-icons">delete_sweep</i> {% trans 'Remove' %}</a></li> |
| 22 | 22 | </ul> |
| 23 | 23 | </div> |
| 24 | 24 | {% endif %} |
| 25 | 25 | </div> |
| 26 | 26 | </h3> |
| 27 | - <div class="card-data"> | |
| 28 | - <p class="comment-date"><i class="fa fa-clock-o"></i> {{ post.post_date }}</p> | |
| 27 | + <div class="post_content"> | |
| 28 | + <div class="card-data"> | |
| 29 | + <p class="comment-date"> | |
| 30 | + <i class="fa fa-clock-o"></i> {{ post.post_date }} | |
| 31 | + {% if post.is_modified %} | |
| 32 | + <em> - {% trans 'Edited' %}</em> | |
| 33 | + {% endif %} | |
| 34 | + </p> | |
| 35 | + </div> | |
| 36 | + <p class="comment-text">{{ post.message|linebreaks }}</p> | |
| 29 | 37 | </div> |
| 30 | - <p class="comment-text">{{ post.message|linebreaks }}</p> | |
| 31 | 38 | <div class="answer_post"></div> |
| 32 | 39 | </div> |
| 33 | 40 | </div> | ... | ... |
forum/templates/post/post_render.html
| ... | ... | @@ -15,17 +15,24 @@ |
| 15 | 15 | <i class="material-icons">more_horiz</i> |
| 16 | 16 | </a> |
| 17 | 17 | <ul class="dropdown-menu" aria-labelledby="dropdownMenu1"> |
| 18 | - <li><a href="javascript:void(0)"><i class="material-icons">create</i> {% trans 'Edit' %}</a></li> | |
| 18 | + <li><a href="javascript:edit_post('{% url 'forum:update_post' post.id %}', '{{ post.id }}')"></li> | |
| 19 | 19 | <li><a href="javascript:delete_post('{% url 'forum:delete_post' post.id %}', '{{ post.id }}')"><i class="material-icons">delete_sweep</i> {% trans 'Remove' %}</a></li> |
| 20 | 20 | </ul> |
| 21 | 21 | </div> |
| 22 | 22 | {% endif %} |
| 23 | 23 | </div> |
| 24 | 24 | </h3> |
| 25 | - <div class="card-data"> | |
| 26 | - <p class="comment-date"><i class="fa fa-clock-o"></i> {{ post.post_date }}</p> | |
| 25 | + <div class="post_content"> | |
| 26 | + <div class="card-data"> | |
| 27 | + <p class="comment-date"> | |
| 28 | + <i class="fa fa-clock-o"></i> {{ post.post_date }} | |
| 29 | + {% if post.post_date != post.modifiction_date %} | |
| 30 | + <em> - {% trans 'Edited' %}</em> | |
| 31 | + {% endif %} | |
| 32 | + </p> | |
| 33 | + </div> | |
| 34 | + <p class="comment-text">{{ post.message|linebreaks }}</p> | |
| 27 | 35 | </div> |
| 28 | - <p class="comment-text">{{ post.message|linebreaks }}</p> | |
| 29 | 36 | <div class="answer_post"></div> |
| 30 | 37 | </div> |
| 31 | 38 | </div> |
| 32 | 39 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -0,0 +1,37 @@ |
| 1 | +{% load i18n permission_tags list_post %} | |
| 2 | +{% load widget_tweaks %} | |
| 3 | + | |
| 4 | +<form class="edit_post_form" method="post" action="{% url 'forum:update_post' post.id %}" enctype="multipart/form-data"> | |
| 5 | + {% csrf_token %} | |
| 6 | + {% for field in form %} | |
| 7 | + {% if field.field.widget.input_type == 'hidden' %} | |
| 8 | + {% render_field field class='form-control' %} | |
| 9 | + {% else %} | |
| 10 | + <div class="form-group {% if form.has_error %} has-error {% endif %} is-fileinput"> | |
| 11 | + <div class="input-group"> | |
| 12 | + {% render_field field class='form-control' placeholder="Post a message" %} | |
| 13 | + <span class="help-block">{{ field.help_text }}</span> | |
| 14 | + {% if field.errors %} | |
| 15 | + <div class="row"> | |
| 16 | + <br /> | |
| 17 | + <div class="alert alert-danger alert-dismissible" role="alert"> | |
| 18 | + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> | |
| 19 | + <span aria-hidden="true">×</span> | |
| 20 | + </button> | |
| 21 | + <ul> | |
| 22 | + {% for error in field.errors %} | |
| 23 | + <li>{{ error }}</li> | |
| 24 | + {% endfor %} | |
| 25 | + </ul> | |
| 26 | + </div> | |
| 27 | + </div> | |
| 28 | + {% endif %} | |
| 29 | + </div> | |
| 30 | + </div> | |
| 31 | + <div class="pull-right"> | |
| 32 | + <button type="button" onclick="cancelEditPost('{{ post.id }}')" class="btn btn-danger btn-raised">{% trans 'Cancel' %}</button> | |
| 33 | + <button type="submit" class="btn btn-primary btn-raised">{% trans 'Save changes' %}</button> | |
| 34 | + </div> | |
| 35 | + {% endif %} | |
| 36 | + {% endfor %} | |
| 37 | +</form> | |
| 0 | 38 | \ No newline at end of file | ... | ... |
forum/templatetags/list_post.py
| ... | ... | @@ -14,6 +14,6 @@ def list_posts(request, forum): |
| 14 | 14 | 'request': request, |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | - context['posts'] = Post.objects.filter(forum = forum) | |
| 17 | + context['posts'] = Post.objects.filter(forum = forum).order_by('post_date') | |
| 18 | 18 | |
| 19 | 19 | return context |
| 20 | 20 | \ No newline at end of file | ... | ... |
forum/urls.py
| ... | ... | @@ -6,10 +6,10 @@ from . import views |
| 6 | 6 | urlpatterns = [ |
| 7 | 7 | url(r'^$', views.ForumIndex.as_view(), name='index'), |
| 8 | 8 | url(r'^create$', views.CreateForumView.as_view(), name='create'), |
| 9 | - url(r'^posts$', views.PostIndex.as_view(), name='posts'), | |
| 10 | 9 | url(r'^create_post$', views.CreatePostView.as_view(), name='create_post'), |
| 11 | - url(r'^render_post/([\w_-]+)/$', views.render_post, name='render_post'), | |
| 10 | + url(r'^update_post/(?P<pk>[\w_-]+)/$', views.PostUpdateView.as_view(), name='update_post'), | |
| 12 | 11 | url(r'^delete_post/(?P<pk>[\w_-]+)/$', views.PostDeleteView.as_view(), name='delete_post'), |
| 12 | + url(r'^render_post/([\w_-]+)/$', views.render_post, name='render_post'), | |
| 13 | 13 | url(r'^post_deleted/$', views.post_deleted, name='deleted_post'), |
| 14 | 14 | url(r'^post_answers$', views.PostAnswerIndex.as_view(), name='post_answers'), |
| 15 | 15 | url(r'^reply_post$', views.CreatePostAnswerView.as_view(), name='reply_post'), | ... | ... |
forum/views.py
| ... | ... | @@ -36,20 +36,6 @@ class CreateForumView(LoginRequiredMixin, generic.edit.CreateView): |
| 36 | 36 | form_class = ForumForm |
| 37 | 37 | success_url = reverse_lazy('forum:index') |
| 38 | 38 | |
| 39 | -class PostIndex(LoginRequiredMixin, generic.ListView): | |
| 40 | - login_url = reverse_lazy("core:home") | |
| 41 | - redirect_field_name = 'next' | |
| 42 | - | |
| 43 | - template_name = "post/post_list.html" | |
| 44 | - context_object_name = 'posts' | |
| 45 | - | |
| 46 | - def get_queryset(self): | |
| 47 | - forum = get_object_or_404(Forum, slug = self.request.GET.get('forum', '')) | |
| 48 | - | |
| 49 | - context = Post.objects.filter(forum = forum) | |
| 50 | - | |
| 51 | - return context | |
| 52 | - | |
| 53 | 39 | class CreatePostView(LoginRequiredMixin, generic.edit.CreateView): |
| 54 | 40 | login_url = reverse_lazy("core:home") |
| 55 | 41 | redirect_field_name = 'next' |
| ... | ... | @@ -77,6 +63,19 @@ def render_post(request, post): |
| 77 | 63 | |
| 78 | 64 | return render(request, "post/post_render.html", context) |
| 79 | 65 | |
| 66 | +class PostUpdateView(LoginRequiredMixin, generic.UpdateView): | |
| 67 | + login_url = reverse_lazy("core:home") | |
| 68 | + redirect_field_name = 'next' | |
| 69 | + | |
| 70 | + form_class = PostForm | |
| 71 | + model = Post | |
| 72 | + template_name = "post/post_update_form.html" | |
| 73 | + | |
| 74 | + def get_success_url(self): | |
| 75 | + self.success_url = reverse('forum:render_post', args = (self.object.id, )) | |
| 76 | + | |
| 77 | + return self.success_url | |
| 78 | + | |
| 80 | 79 | class PostDeleteView(LoginRequiredMixin, generic.DeleteView): |
| 81 | 80 | login_url = reverse_lazy("core:home") |
| 82 | 81 | redirect_field_name = 'next' | ... | ... |