Commit e376ec1c65c67f85074a8c4cb258aecb7391b193
1 parent
fc0ed422
Exists in
master
and in
5 other branches
Adding posts visualization [Issue: #73]
Showing
14 changed files
with
208 additions
and
48 deletions
Show diff stats
amadeus/settings.py
core/static/css/base/amadeus.css
| ... | ... | @@ -271,3 +271,29 @@ a.alert_message:hover{color : grey} |
| 271 | 271 | .accordion_list { |
| 272 | 272 | background: #e0e0e0; |
| 273 | 273 | } |
| 274 | + | |
| 275 | +.forum_collapse { | |
| 276 | + color: #000; | |
| 277 | +} | |
| 278 | +.forum_collapse:hover, .forum_collapse:focus { | |
| 279 | + text-decoration: none; | |
| 280 | + color: #000; | |
| 281 | +} | |
| 282 | + | |
| 283 | +.timeline.post { | |
| 284 | + border-top-left-radius: 8px; | |
| 285 | + border-top-right-radius: 8px; | |
| 286 | + padding-bottom: 0px; | |
| 287 | + -webkit-padding-start: 0px !important; | |
| 288 | + width: 100%; | |
| 289 | +} | |
| 290 | +.timeline.post li { | |
| 291 | + padding: 10px; | |
| 292 | + border-bottom: 1px solid #fff; | |
| 293 | +} | |
| 294 | +.timeline.post li:last-child { | |
| 295 | + border: none; | |
| 296 | +} | |
| 297 | +.timeline.post h3 { | |
| 298 | + margin-top: 5px; | |
| 299 | +} | |
| 274 | 300 | \ No newline at end of file | ... | ... |
courses/templates/subject/form_view_teacher.html
| ... | ... | @@ -27,6 +27,25 @@ |
| 27 | 27 | |
| 28 | 28 | $(".forum_form").show(); |
| 29 | 29 | } |
| 30 | + | |
| 31 | + var postsUrl = '{% url "forum:posts" %}'; | |
| 32 | + var formPostsUrl = ''; | |
| 33 | + | |
| 34 | + function showPosts(forum) { | |
| 35 | + if ($("#collapse" + forum).hasClass('in')) { | |
| 36 | + $("#collapse" + forum).collapse('hide'); | |
| 37 | + } else { | |
| 38 | + $.ajax({ | |
| 39 | + url: postsUrl, | |
| 40 | + data: {'forum': forum}, | |
| 41 | + success: function(data) { | |
| 42 | + $("#collapse" + forum).find(".well").html(data); | |
| 43 | + } | |
| 44 | + }); | |
| 45 | + | |
| 46 | + $("#collapse" + forum).collapse('show'); | |
| 47 | + } | |
| 48 | + } | |
| 30 | 49 | </script> |
| 31 | 50 | {% endblock %} |
| 32 | 51 | ... | ... |
forum/admin.py
| 1 | 1 | from django.contrib import admin |
| 2 | 2 | |
| 3 | -# Register your models here. | |
| 3 | +from .models import Forum, Post, PostAnswer | |
| 4 | + | |
| 5 | +class ForumAdmin(admin.ModelAdmin): | |
| 6 | + list_display = ['name', 'slug'] | |
| 7 | + search_fields = ['name', 'slug'] | |
| 8 | + | |
| 9 | +class PostAdmin(admin.ModelAdmin): | |
| 10 | + list_display = ['user', 'forum'] | |
| 11 | + search_fields = ['user', 'forum'] | |
| 12 | + | |
| 13 | +class PostAnswerAdmin(admin.ModelAdmin): | |
| 14 | + list_display = ['user', 'post', 'answer_date'] | |
| 15 | + search_fields = ['user'] | |
| 16 | + | |
| 17 | +admin.site.register(Forum, ForumAdmin) | |
| 18 | +admin.site.register(Post, PostAdmin) | |
| 19 | +admin.site.register(PostAnswer, PostAnswerAdmin) | |
| 4 | 20 | \ No newline at end of file | ... | ... |
forum/forms.py
| ... | ... | @@ -6,13 +6,13 @@ class ForumForm(forms.ModelForm): |
| 6 | 6 | |
| 7 | 7 | class Meta: |
| 8 | 8 | model = Forum |
| 9 | - fields = ('title', 'description') | |
| 9 | + fields = ('name', 'description') | |
| 10 | 10 | labels = { |
| 11 | - 'title': _('Title'), | |
| 11 | + 'name': _('Title'), | |
| 12 | 12 | 'description': _('Description') |
| 13 | 13 | } |
| 14 | 14 | help_texts = { |
| 15 | - 'title': _('Forum title'), | |
| 15 | + 'name': _('Forum title'), | |
| 16 | 16 | 'description': _('What is this forum about?') |
| 17 | 17 | } |
| 18 | 18 | widgets = { | ... | ... |
| ... | ... | @@ -0,0 +1,61 @@ |
| 1 | +# -*- coding: utf-8 -*- | |
| 2 | +# Generated by Django 1.10 on 2016-09-22 20:41 | |
| 3 | +from __future__ import unicode_literals | |
| 4 | + | |
| 5 | +from django.conf import settings | |
| 6 | +from django.db import migrations, models | |
| 7 | +import django.db.models.deletion | |
| 8 | + | |
| 9 | + | |
| 10 | +class Migration(migrations.Migration): | |
| 11 | + | |
| 12 | + initial = True | |
| 13 | + | |
| 14 | + dependencies = [ | |
| 15 | + migrations.swappable_dependency(settings.AUTH_USER_MODEL), | |
| 16 | + ('courses', '0001_initial'), | |
| 17 | + ] | |
| 18 | + | |
| 19 | + operations = [ | |
| 20 | + migrations.CreateModel( | |
| 21 | + name='Forum', | |
| 22 | + fields=[ | |
| 23 | + ('activity_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='courses.Activity')), | |
| 24 | + ('title', models.CharField(max_length=100, verbose_name='Title')), | |
| 25 | + ('description', models.TextField(blank=True, verbose_name='Description')), | |
| 26 | + ], | |
| 27 | + options={ | |
| 28 | + 'verbose_name': 'Forum', | |
| 29 | + 'verbose_name_plural': 'Foruns', | |
| 30 | + }, | |
| 31 | + bases=('courses.activity',), | |
| 32 | + ), | |
| 33 | + migrations.CreateModel( | |
| 34 | + name='Post', | |
| 35 | + fields=[ | |
| 36 | + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |
| 37 | + ('message', models.TextField(verbose_name='Post message')), | |
| 38 | + ('post_date', models.DateTimeField(auto_now_add=True, verbose_name='Post Date')), | |
| 39 | + ('forum', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='forum.Forum', verbose_name='Forum')), | |
| 40 | + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Autor')), | |
| 41 | + ], | |
| 42 | + options={ | |
| 43 | + 'verbose_name': 'Post', | |
| 44 | + 'verbose_name_plural': 'Posts', | |
| 45 | + }, | |
| 46 | + ), | |
| 47 | + migrations.CreateModel( | |
| 48 | + name='PostAnswer', | |
| 49 | + fields=[ | |
| 50 | + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |
| 51 | + ('message', models.TextField(verbose_name='Answer message')), | |
| 52 | + ('answer_date', models.DateTimeField(auto_now_add=True, verbose_name='Answer Date')), | |
| 53 | + ('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='forum.Post', verbose_name='Post')), | |
| 54 | + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Autor')), | |
| 55 | + ], | |
| 56 | + options={ | |
| 57 | + 'verbose_name': 'Post Answer', | |
| 58 | + 'verbose_name_plural': 'Post Answers', | |
| 59 | + }, | |
| 60 | + ), | |
| 61 | + ] | ... | ... |
| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | +# -*- coding: utf-8 -*- | |
| 2 | +# Generated by Django 1.10 on 2016-09-22 20:43 | |
| 3 | +from __future__ import unicode_literals | |
| 4 | + | |
| 5 | +from django.db import migrations | |
| 6 | + | |
| 7 | + | |
| 8 | +class Migration(migrations.Migration): | |
| 9 | + | |
| 10 | + dependencies = [ | |
| 11 | + ('forum', '0001_initial'), | |
| 12 | + ] | |
| 13 | + | |
| 14 | + operations = [ | |
| 15 | + migrations.RemoveField( | |
| 16 | + model_name='forum', | |
| 17 | + name='title', | |
| 18 | + ), | |
| 19 | + ] | ... | ... |
forum/models.py
| ... | ... | @@ -34,7 +34,7 @@ class Post(models.Model): |
| 34 | 34 | verbose_name_plural = _('Posts') |
| 35 | 35 | |
| 36 | 36 | def __str__(self): |
| 37 | - return ''.join([self.user.name, " / ", self.post_date]) | |
| 37 | + return ''.join([self.user.name, " / ", str(self.post_date)]) | |
| 38 | 38 | |
| 39 | 39 | """ |
| 40 | 40 | It represents an answer to a forum's post | ... | ... |
forum/templates/forum_list.html
| ... | ... | @@ -2,10 +2,16 @@ |
| 2 | 2 | |
| 3 | 3 | {% if foruns|length > 0 %} |
| 4 | 4 | {% for forum in foruns %} |
| 5 | - <div class="page-header"> | |
| 6 | - <h1 id="timeline">{{ forum }}</h1> | |
| 7 | - <b>Descricao: </b>{{ forum.description }}<p> | |
| 8 | - <b>Abertura: </b>{{ forum.create_date }} | |
| 5 | + <a class="forum_collapse" role="button" href="javascript: showPosts('{{ forum.slug }}')" aria-expanded="false"> | |
| 6 | + <div class="page-header"> | |
| 7 | + <h1 id="timeline">{{ forum }}</h1> | |
| 8 | + <b>{% trans 'Description' %}: </b>{{ forum.description }}<p> | |
| 9 | + <b>{% trans 'Created in' %}: </b>{{ forum.create_date }} | |
| 10 | + </div> | |
| 11 | + </a> | |
| 12 | + <div class="collapse" id="collapse{{ forum.slug }}"> | |
| 13 | + <div class="well"> | |
| 14 | + </div> | |
| 9 | 15 | </div> |
| 10 | 16 | {% endfor %} |
| 11 | 17 | {% else %} |
| ... | ... | @@ -13,39 +19,3 @@ |
| 13 | 19 | <p>{% trans 'No forum created yet.' %}</p> |
| 14 | 20 | </div> |
| 15 | 21 | {% endif %} |
| 16 | -<!-- <ul class="timeline"> | |
| 17 | - <li> | |
| 18 | - <div class="timeline-badge"> | |
| 19 | - <img id="logo" src="https://uxdesign-html-japm94.c9users.io/atividades-amadeus/uxdesign-html/img/topo-amadeus.png"> | |
| 20 | - </div> | |
| 21 | - <p></p> | |
| 22 | - <div class="timeline-panel"> | |
| 23 | - <div class="timeline-heading"> | |
| 24 | - <h4 class="timeline-title">Python is insteresting</h4> | |
| 25 | - <p><small class="text-muted"><i class="glyphicon glyphicon-time"></i> 11 hours ago by </small>Carlos </p> | |
| 26 | - </div> | |
| 27 | - <div class="timeline-body"> | |
| 28 | - <p>Who knows how working a String in python?</p> | |
| 29 | - </div> | |
| 30 | - <hr> | |
| 31 | - <i class="fa fa-pencil-square-o fa-2x" aria-hidden="true"></i> | |
| 32 | - </div> | |
| 33 | - </li> | |
| 34 | - <li> | |
| 35 | - <div class="timeline-badge"> | |
| 36 | - <img id="logo" src="https://uxdesign-html-japm94.c9users.io/atividades-amadeus/uxdesign-html/img/topo-amadeus.png"> | |
| 37 | - </div> | |
| 38 | - <p></p> | |
| 39 | - <div class="timeline-panel"> | |
| 40 | - <div class="timeline-heading"> | |
| 41 | - <h4 class="timeline-title">Ruby's doubt</h4> | |
| 42 | - <p><small class="text-muted"><i class="glyphicon glyphicon-time"></i> 5 hours ago by </small>Jurandi</p> | |
| 43 | - </div> | |
| 44 | - <div class="timeline-body"> | |
| 45 | - <p>How works the Gems?</p> | |
| 46 | - </div> | |
| 47 | - <hr> | |
| 48 | - <i class="fa fa-pencil-square-o fa-2x" aria-hidden="true"></i> | |
| 49 | - </div> | |
| 50 | - </li> | |
| 51 | -</ul> --> | |
| 52 | 22 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -0,0 +1,34 @@ |
| 1 | +{% load i18n %} | |
| 2 | + | |
| 3 | +{% if posts|length > 0 %} | |
| 4 | + <ul class="timeline post"> | |
| 5 | + {% for post in posts %} | |
| 6 | + <li> | |
| 7 | + <div class="timeline-panel"> | |
| 8 | + <div class="row"> | |
| 9 | + <div class="col-xs-2 col-sm-2 col-md-2"> | |
| 10 | + <img class="img-responsive img-rounded" src="{{ post.user.image_url }}" /> | |
| 11 | + </div> | |
| 12 | + <div class="col-xs-10 col-sm-10 col-md-10"> | |
| 13 | + <div class="timeline-heading"> | |
| 14 | + <h3> {{ post.user }}</h3> | |
| 15 | + </div> | |
| 16 | + <div class="timeline-body"> | |
| 17 | + <p><em>{{ post.message|linebreaks }}</em></p> | |
| 18 | + </div> | |
| 19 | + <hr> | |
| 20 | + <small class="text-muted"> | |
| 21 | + <span class="pull-right"> | |
| 22 | + <i class="glyphicon glyphicon-time"></i> {{ post.post_date|timesince }} | |
| 23 | + {% trans ' ago' %} | |
| 24 | + </span> | |
| 25 | + </small> | |
| 26 | + </div> | |
| 27 | + </div> | |
| 28 | + </div> | |
| 29 | + </li> | |
| 30 | + {% endfor %} | |
| 31 | + </ul> | |
| 32 | +{% else %} | |
| 33 | + <p>{% trans 'No posts were made yet.' %}</p> | |
| 34 | +{% endif %} | |
| 0 | 35 | \ No newline at end of file | ... | ... |
forum/urls.py
forum/views.py
| ... | ... | @@ -4,7 +4,7 @@ from django.utils.translation import ugettext_lazy as _ |
| 4 | 4 | from django.views import generic |
| 5 | 5 | from django.contrib.auth.mixins import LoginRequiredMixin |
| 6 | 6 | |
| 7 | -from .models import Forum | |
| 7 | +from .models import Forum, Post | |
| 8 | 8 | from courses.models import Topic |
| 9 | 9 | |
| 10 | 10 | from .forms import ForumForm |
| ... | ... | @@ -27,4 +27,18 @@ class CreateForumView(LoginRequiredMixin, generic.edit.CreateView): |
| 27 | 27 | |
| 28 | 28 | template_name = 'forum_form.html' |
| 29 | 29 | form_class = ForumForm |
| 30 | - success_url = reverse_lazy('forum:index') | |
| 31 | 30 | \ No newline at end of file |
| 31 | + success_url = reverse_lazy('forum:index') | |
| 32 | + | |
| 33 | +class PostIndex(LoginRequiredMixin, generic.ListView): | |
| 34 | + login_url = reverse_lazy("core:home") | |
| 35 | + redirect_field_name = 'next' | |
| 36 | + | |
| 37 | + template_name = "post_list.html" | |
| 38 | + context_object_name = 'posts' | |
| 39 | + | |
| 40 | + def get_queryset(self): | |
| 41 | + forum = get_object_or_404(Forum, slug = self.request.GET.get('forum', '')) | |
| 42 | + | |
| 43 | + context = Post.objects.filter(forum = forum) | |
| 44 | + | |
| 45 | + return context | |
| 32 | 46 | \ No newline at end of file | ... | ... |