Commit d4e29336cddf18369319311b0268ee15d2604b3b

Authored by ailsoncgt
2 parents 3cce9169 afce7b17

Merge

core/tests.py
... ... @@ -89,7 +89,7 @@ class RegisterUserTestCase(TestCase):
89 89 }
90 90  
91 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 94 data = {
95 95 'username': '',
... ... @@ -102,7 +102,7 @@ class RegisterUserTestCase(TestCase):
102 102 'gender': 'F',
103 103 }
104 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 107 class RememberPasswordTestCase(TestCase):
108 108  
... ... @@ -194,7 +194,7 @@ class UpdateUserTestCase(TestCase):
194 194 'gender': 'F',
195 195 }
196 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 200 class DeleteUserTestCase(TestCase):
... ...
courses/templates/subject/form_view_teacher.html
... ... @@ -32,16 +32,6 @@
32 32 <div class="modal-body">
33 33 <section>
34 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 35 </section>
46 36 </div>
47 37 <div class="modal-footer">
... ...
forum/forms.py
1 1 from django import forms
2 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 5 class ForumForm(forms.ModelForm):
6 6  
... ... @@ -19,6 +19,19 @@ class ForumForm(forms.ModelForm):
19 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 35 class PostAnswerForm(forms.ModelForm):
23 36  
24 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 20 * Function to load forum to modal
... ... @@ -9,12 +26,45 @@ function showForum(url, forum_id) {
9 26 data: {'forum_id': forum_id},
10 27 success: function(data) {
11 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 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 68 function answer(id, url) {
19 69 $.ajax({
20 70 url: url,
... ...
forum/templates/forum/forum_list.html
1 1 {% load i18n permission_tags list_post %}
  2 +{% load widget_tweaks %}
2 3  
3 4 <div class="comments-list">
4 5 <div class="section-heading">
... ... @@ -8,7 +9,45 @@
8 9 </div>
9 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 52 <!--{% if foruns|length > 0 %}
14 53 {% for forum in foruns %}
... ...
forum/templates/post/post_list.html
... ... @@ -11,13 +11,14 @@
11 11 <i class="material-icons">reply</i>
12 12 </a>
13 13 {% if request.user|has_role:'system_admin' or request.user|has_role:'professor' and request.user == post.user %}
  14 + {% csrf_token %}
14 15 <div class="btn-group icon-more-horiz">
15 16 <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
16 17 <i class="material-icons">more_horiz</i>
17 18 </a>
18 19 <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
19 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 22 </ul>
22 23 </div>
23 24 {% endif %}
... ...
forum/templates/post/post_render.html 0 → 100644
... ... @@ -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 32 \ No newline at end of file
... ...
forum/templates/post_answers/post_answer_form.html
... ... @@ -25,7 +25,7 @@
25 25 </div>
26 26 {% endif %}
27 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 29 <i class="material-icons">send</i>
30 30 </button>
31 31 </span>
... ...
forum/urls.py
... ... @@ -7,6 +7,10 @@ urlpatterns = [
7 7 url(r'^$', views.ForumIndex.as_view(), name='index'),
8 8 url(r'^create$', views.CreateForumView.as_view(), name='create'),
9 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 14 url(r'^post_answers$', views.PostAnswerIndex.as_view(), name='post_answers'),
11 15 url(r'^reply_post$', views.CreatePostAnswerView.as_view(), name='reply_post'),
12 16 ]
... ...
forum/views.py
  1 +from django.http import HttpResponse
1 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 4 from django.utils.translation import ugettext_lazy as _
4 5 from django.views import generic
5 6 from django.contrib.auth.mixins import LoginRequiredMixin
... ... @@ -7,7 +8,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin
7 8 from .models import Forum, Post, PostAnswer
8 9 from courses.models import Topic
9 10  
10   -from .forms import ForumForm, PostAnswerForm
  11 +from .forms import ForumForm, PostForm, PostAnswerForm
11 12  
12 13 class ForumIndex(LoginRequiredMixin, generic.ListView):
13 14 login_url = reverse_lazy("core:home")
... ... @@ -20,6 +21,12 @@ class ForumIndex(LoginRequiredMixin, generic.ListView):
20 21 forum_id = self.request.GET.get('forum_id', 0)
21 22  
22 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 31 return context
25 32  
... ... @@ -43,6 +50,44 @@ class PostIndex(LoginRequiredMixin, generic.ListView):
43 50  
44 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 91 class PostAnswerIndex(LoginRequiredMixin, generic.ListView):
47 92 login_url = reverse_lazy("core:home")
48 93 redirect_field_name = 'next'
... ...
requirements.txt
... ... @@ -10,7 +10,6 @@ itsdangerous==0.24
10 10 Jinja2==2.8
11 11 MarkupSafe==0.23
12 12 Pillow==3.3.1
13   -pkg-resources==0.0.0
14 13 pycpfcnpj==1.0.2
15 14 six==1.10.0
16 15 slugify==0.0.1
... ...