Commit d4e29336cddf18369319311b0268ee15d2604b3b

Authored by ailsoncgt
2 parents 3cce9169 afce7b17

Merge

@@ -89,7 +89,7 @@ class RegisterUserTestCase(TestCase): @@ -89,7 +89,7 @@ class RegisterUserTestCase(TestCase):
89 } 89 }
90 90
91 response = self.client.post(self.url, data) 91 response = self.client.post(self.url, data)
92 - self.assertFormError(response, 'form', 'email', 'Insira um endereço de email válido.') 92 + self.assertFormError(response, 'form', 'email', 'Enter a valid email address.')
93 93
94 data = { 94 data = {
95 'username': '', 95 'username': '',
@@ -102,7 +102,7 @@ class RegisterUserTestCase(TestCase): @@ -102,7 +102,7 @@ class RegisterUserTestCase(TestCase):
102 'gender': 'F', 102 'gender': 'F',
103 } 103 }
104 response = self.client.post(self.url, data) 104 response = self.client.post(self.url, data)
105 - self.assertFormError(response, 'form', 'username', 'Este campo é obrigatório.') 105 + self.assertFormError(response, 'form', 'username', 'This field is required.')
106 106
107 class RememberPasswordTestCase(TestCase): 107 class RememberPasswordTestCase(TestCase):
108 108
@@ -194,7 +194,7 @@ class UpdateUserTestCase(TestCase): @@ -194,7 +194,7 @@ class UpdateUserTestCase(TestCase):
194 'gender': 'F', 194 'gender': 'F',
195 } 195 }
196 response = self.client.post(self.url, data) 196 response = self.client.post(self.url, data)
197 - self.assertFormError(response, 'form', 'username', 'Este campo é obrigatório.') 197 + self.assertFormError(response, 'form', 'username', 'This field is required.')
198 198
199 199
200 class DeleteUserTestCase(TestCase): 200 class DeleteUserTestCase(TestCase):
courses/templates/subject/form_view_teacher.html
@@ -32,16 +32,6 @@ @@ -32,16 +32,6 @@
32 <div class="modal-body"> 32 <div class="modal-body">
33 <section> 33 <section>
34 <div class="forum_topics"></div> 34 <div class="forum_topics"></div>
35 - <div class="form-group">  
36 - <div class="input-group">  
37 - <textarea type="text" id="addon3a" class="form-control" placeholder="{% trans 'Post a comment...' %}"></textarea>  
38 - <span class="input-group-btn">  
39 - <button type="button" class="btn btn-fab btn-fab-mini">  
40 - <i class="material-icons">send</i>  
41 - </button>  
42 - </span>  
43 - </div>  
44 - </div>  
45 </section> 35 </section>
46 </div> 36 </div>
47 <div class="modal-footer"> 37 <div class="modal-footer">
forum/forms.py
1 from django import forms 1 from django import forms
2 from django.utils.translation import ugettext_lazy as _ 2 from django.utils.translation import ugettext_lazy as _
3 -from .models import Forum, PostAnswer 3 +from .models import Forum, Post, PostAnswer
4 4
5 class ForumForm(forms.ModelForm): 5 class ForumForm(forms.ModelForm):
6 6
@@ -19,6 +19,19 @@ class ForumForm(forms.ModelForm): @@ -19,6 +19,19 @@ class ForumForm(forms.ModelForm):
19 'description': forms.Textarea(attrs={'cols': 80, 'rows': 5}), 19 'description': forms.Textarea(attrs={'cols': 80, 'rows': 5}),
20 } 20 }
21 21
  22 +class PostForm(forms.ModelForm):
  23 +
  24 + class Meta:
  25 + model = Post
  26 + fields = ('message', 'forum', )
  27 + labels = {
  28 + 'message': _('Message')
  29 + }
  30 + widgets = {
  31 + 'message': forms.Textarea(attrs={'cols': 80, 'rows': 3}),
  32 + 'forum': forms.HiddenInput(),
  33 + }
  34 +
22 class PostAnswerForm(forms.ModelForm): 35 class PostAnswerForm(forms.ModelForm):
23 36
24 class Meta: 37 class Meta:
forum/static/js/forum.js
  1 +function getCookie(name) {
  2 + var cookieValue = null;
  3 + if (document.cookie && document.cookie !== '') {
  4 + var cookies = document.cookie.split(';');
  5 + for (var i = 0; i < cookies.length; i++) {
  6 + var cookie = jQuery.trim(cookies[i]);
  7 + // Does this cookie string begin with the name we want?
  8 + if (cookie.substring(0, name.length + 1) === (name + '=')) {
  9 + cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
  10 + break;
  11 + }
  12 + }
  13 + }
  14 + return cookieValue;
  15 +}
  16 +
  17 +
1 /* 18 /*
2 * 19 *
3 * Function to load forum to modal 20 * Function to load forum to modal
@@ -9,12 +26,45 @@ function showForum(url, forum_id) { @@ -9,12 +26,45 @@ function showForum(url, forum_id) {
9 data: {'forum_id': forum_id}, 26 data: {'forum_id': forum_id},
10 success: function(data) { 27 success: function(data) {
11 $(".forum_topics").html(data); 28 $(".forum_topics").html(data);
  29 +
  30 + var frm = $('#form_post');
  31 + frm.submit(function () {
  32 + $.ajax({
  33 + type: frm.attr('method'),
  34 + url: frm.attr('action'),
  35 + data: frm.serialize(),
  36 + success: function (data) {
  37 + $("#posts_list").append(data);
  38 + frm[0].reset();
  39 + },
  40 + error: function(data) {
  41 + console.log(frm.serialize());
  42 + console.log('Error');
  43 + }
  44 + });
  45 + return false;
  46 + });
12 } 47 }
13 }); 48 });
14 49
15 $('#forumModal').modal(); 50 $('#forumModal').modal();
16 } 51 }
17 52
  53 +function delete_post(url, post) {
  54 + var csrftoken = getCookie('csrftoken');
  55 +
  56 + $.ajax({
  57 + method: 'post',
  58 + beforeSend: function (request) {
  59 + request.setRequestHeader('X-CSRFToken', csrftoken);
  60 + },
  61 + url: url,
  62 + success: function(data) {
  63 + $("#post_"+post).remove();
  64 + }
  65 + });
  66 +}
  67 +
18 function answer(id, url) { 68 function answer(id, url) {
19 $.ajax({ 69 $.ajax({
20 url: url, 70 url: url,
forum/templates/forum/forum_list.html
1 {% load i18n permission_tags list_post %} 1 {% load i18n permission_tags list_post %}
  2 +{% load widget_tweaks %}
2 3
3 <div class="comments-list"> 4 <div class="comments-list">
4 <div class="section-heading"> 5 <div class="section-heading">
@@ -8,7 +9,45 @@ @@ -8,7 +9,45 @@
8 </div> 9 </div>
9 </div> 10 </div>
10 11
11 -{% list_posts request forum %} 12 +<div id="posts_list">
  13 + {% list_posts request forum %}
  14 +</div>
  15 +
  16 +<form id="form_post" method="post" action="{% url 'forum:create_post' %}" enctype="multipart/form-data">
  17 + {% csrf_token %}
  18 + {% for field in form %}
  19 + {% if field.field.widget.input_type == 'hidden' %}
  20 + {% render_field field class='form-control' value=forum.id %}
  21 + {% else %}
  22 + <div class="form-group {% if form.has_error %} has-error {% endif %} is-fileinput">
  23 + <div class="input-group">
  24 + {% render_field field class='form-control' placeholder="Post a message" %}
  25 + <span class="help-block">{{ field.help_text }}</span>
  26 + {% if field.errors %}
  27 + <div class="row">
  28 + <br />
  29 + <div class="alert alert-danger alert-dismissible" role="alert">
  30 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  31 + <span aria-hidden="true">&times;</span>
  32 + </button>
  33 + <ul>
  34 + {% for error in field.errors %}
  35 + <li>{{ error }}</li>
  36 + {% endfor %}
  37 + </ul>
  38 + </div>
  39 + </div>
  40 + {% endif %}
  41 + <span class="input-group-btn">
  42 + <button type="submit" class="btn btn-fab btn-fab-mini">
  43 + <i class="material-icons">send</i>
  44 + </button>
  45 + </span>
  46 + </div>
  47 + </div>
  48 + {% endif %}
  49 + {% endfor %}
  50 +</form>
12 51
13 <!--{% if foruns|length > 0 %} 52 <!--{% if foruns|length > 0 %}
14 {% for forum in foruns %} 53 {% for forum in foruns %}
forum/templates/post/post_list.html
@@ -11,13 +11,14 @@ @@ -11,13 +11,14 @@
11 <i class="material-icons">reply</i> 11 <i class="material-icons">reply</i>
12 </a> 12 </a>
13 {% if request.user|has_role:'system_admin' or request.user|has_role:'professor' and request.user == post.user %} 13 {% if request.user|has_role:'system_admin' or request.user|has_role:'professor' and request.user == post.user %}
  14 + {% csrf_token %}
14 <div class="btn-group icon-more-horiz"> 15 <div class="btn-group icon-more-horiz">
15 <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 16 <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
16 <i class="material-icons">more_horiz</i> 17 <i class="material-icons">more_horiz</i>
17 </a> 18 </a>
18 <ul class="dropdown-menu" aria-labelledby="dropdownMenu1"> 19 <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
19 <li><a href="javascript:void(0)"><i class="material-icons">create</i> {% trans 'Edit' %}</a></li> 20 <li><a href="javascript:void(0)"><i class="material-icons">create</i> {% trans 'Edit' %}</a></li>
20 - <li><a href="javascript:void(0)"><i class="material-icons">delete_sweep</i> {% trans 'Remove' %}</a></li> 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>
21 </ul> 22 </ul>
22 </div> 23 </div>
23 {% endif %} 24 {% endif %}
forum/templates/post/post_render.html 0 → 100644
@@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
  1 +{% load i18n permission_tags %}
  2 +
  3 +<div class="row">
  4 + <div id="post_{{ post.id }}" class="col-sm-12 col-xs-12">
  5 + <h3 class="user-name">
  6 + {{ post.user }}
  7 + <div class="pull-right">
  8 + <a href="javascript:answer('{{ post.id }}', '{% url 'forum:reply_post' %}');">
  9 + <i class="material-icons">reply</i>
  10 + </a>
  11 + {% if request.user|has_role:'system_admin' or request.user|has_role:'professor' and request.user == post.user %}
  12 + {% csrf_token %}
  13 + <div class="btn-group icon-more-horiz">
  14 + <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  15 + <i class="material-icons">more_horiz</i>
  16 + </a>
  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>
  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 + </ul>
  21 + </div>
  22 + {% endif %}
  23 + </div>
  24 + </h3>
  25 + <div class="card-data">
  26 + <p class="comment-date"><i class="fa fa-clock-o"></i> {{ post.post_date }}</p>
  27 + </div>
  28 + <p class="comment-text">{{ post.message|linebreaks }}</p>
  29 + <div class="answer_post"></div>
  30 + </div>
  31 +</div>
0 \ No newline at end of file 32 \ No newline at end of file
forum/templates/post_answers/post_answer_form.html
@@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
25 </div> 25 </div>
26 {% endif %} 26 {% endif %}
27 <span class="input-group-btn"> 27 <span class="input-group-btn">
28 - <button type="button" class="btn btn-fab btn-fab-mini"> 28 + <button type="submit" class="btn btn-fab btn-fab-mini">
29 <i class="material-icons">send</i> 29 <i class="material-icons">send</i>
30 </button> 30 </button>
31 </span> 31 </span>
@@ -7,6 +7,10 @@ urlpatterns = [ @@ -7,6 +7,10 @@ urlpatterns = [
7 url(r'^$', views.ForumIndex.as_view(), name='index'), 7 url(r'^$', views.ForumIndex.as_view(), name='index'),
8 url(r'^create$', views.CreateForumView.as_view(), name='create'), 8 url(r'^create$', views.CreateForumView.as_view(), name='create'),
9 url(r'^posts$', views.PostIndex.as_view(), name='posts'), 9 url(r'^posts$', views.PostIndex.as_view(), name='posts'),
  10 + url(r'^create_post$', views.CreatePostView.as_view(), name='create_post'),
  11 + url(r'^render_post/([\w_-]+)/$', views.render_post, name='render_post'),
  12 + url(r'^delete_post/(?P<pk>[\w_-]+)/$', views.PostDeleteView.as_view(), name='delete_post'),
  13 + url(r'^post_deleted/$', views.post_deleted, name='deleted_post'),
10 url(r'^post_answers$', views.PostAnswerIndex.as_view(), name='post_answers'), 14 url(r'^post_answers$', views.PostAnswerIndex.as_view(), name='post_answers'),
11 url(r'^reply_post$', views.CreatePostAnswerView.as_view(), name='reply_post'), 15 url(r'^reply_post$', views.CreatePostAnswerView.as_view(), name='reply_post'),
12 ] 16 ]
forum/views.py
  1 +from django.http import HttpResponse
1 from django.shortcuts import render, get_object_or_404 2 from django.shortcuts import render, get_object_or_404
2 -from django.core.urlresolvers import reverse_lazy 3 +from django.core.urlresolvers import reverse, reverse_lazy
3 from django.utils.translation import ugettext_lazy as _ 4 from django.utils.translation import ugettext_lazy as _
4 from django.views import generic 5 from django.views import generic
5 from django.contrib.auth.mixins import LoginRequiredMixin 6 from django.contrib.auth.mixins import LoginRequiredMixin
@@ -7,7 +8,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin @@ -7,7 +8,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin
7 from .models import Forum, Post, PostAnswer 8 from .models import Forum, Post, PostAnswer
8 from courses.models import Topic 9 from courses.models import Topic
9 10
10 -from .forms import ForumForm, PostAnswerForm 11 +from .forms import ForumForm, PostForm, PostAnswerForm
11 12
12 class ForumIndex(LoginRequiredMixin, generic.ListView): 13 class ForumIndex(LoginRequiredMixin, generic.ListView):
13 login_url = reverse_lazy("core:home") 14 login_url = reverse_lazy("core:home")
@@ -20,6 +21,12 @@ class ForumIndex(LoginRequiredMixin, generic.ListView): @@ -20,6 +21,12 @@ class ForumIndex(LoginRequiredMixin, generic.ListView):
20 forum_id = self.request.GET.get('forum_id', 0) 21 forum_id = self.request.GET.get('forum_id', 0)
21 22
22 context = Forum.objects.get(id = forum_id) 23 context = Forum.objects.get(id = forum_id)
  24 +
  25 + return context
  26 +
  27 + def get_context_data(self, **kwargs):
  28 + context = super(ForumIndex, self).get_context_data(**kwargs)
  29 + context['form'] = PostForm()
23 30
24 return context 31 return context
25 32
@@ -43,6 +50,44 @@ class PostIndex(LoginRequiredMixin, generic.ListView): @@ -43,6 +50,44 @@ class PostIndex(LoginRequiredMixin, generic.ListView):
43 50
44 return context 51 return context
45 52
  53 +class CreatePostView(LoginRequiredMixin, generic.edit.CreateView):
  54 + login_url = reverse_lazy("core:home")
  55 + redirect_field_name = 'next'
  56 +
  57 + form_class = PostForm
  58 +
  59 + def form_valid(self, form):
  60 + self.object = form.save(commit = False)
  61 + self.object.user = self.request.user
  62 +
  63 + self.object.save()
  64 +
  65 + return super(CreatePostView, self).form_valid(form)
  66 +
  67 + def get_success_url(self):
  68 + self.success_url = reverse('forum:render_post', args = (self.object.id, ))
  69 +
  70 + return self.success_url
  71 +
  72 +def render_post(request, post):
  73 + last_post = get_object_or_404(Post, id = post)
  74 +
  75 + context = {}
  76 + context['post'] = last_post
  77 +
  78 + return render(request, "post/post_render.html", context)
  79 +
  80 +class PostDeleteView(LoginRequiredMixin, generic.DeleteView):
  81 + login_url = reverse_lazy("core:home")
  82 + redirect_field_name = 'next'
  83 +
  84 + model = Post
  85 + pk_url_kwarg = 'pk'
  86 + success_url = reverse_lazy('forum:deleted_post')
  87 +
  88 +def post_deleted(request):
  89 + return HttpResponse(_("Post deleted successfully."))
  90 +
46 class PostAnswerIndex(LoginRequiredMixin, generic.ListView): 91 class PostAnswerIndex(LoginRequiredMixin, generic.ListView):
47 login_url = reverse_lazy("core:home") 92 login_url = reverse_lazy("core:home")
48 redirect_field_name = 'next' 93 redirect_field_name = 'next'
requirements.txt
@@ -10,7 +10,6 @@ itsdangerous==0.24 @@ -10,7 +10,6 @@ itsdangerous==0.24
10 Jinja2==2.8 10 Jinja2==2.8
11 MarkupSafe==0.23 11 MarkupSafe==0.23
12 Pillow==3.3.1 12 Pillow==3.3.1
13 -pkg-resources==0.0.0  
14 pycpfcnpj==1.0.2 13 pycpfcnpj==1.0.2
15 six==1.10.0 14 six==1.10.0
16 slugify==0.0.1 15 slugify==0.0.1