Skip to content

Commit d296c39

Browse files
renzonrenzon
authored andcommitted
Implemented Topics
close #276
1 parent efcbe4e commit d296c39

File tree

15 files changed

+236
-17
lines changed

15 files changed

+236
-17
lines changed

pythonpro/modules/admin.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from django.contrib import admin
22
from ordered_model.admin import OrderedModelAdmin
33

4-
from pythonpro.modules.models import Section, Module, Chapter
4+
from pythonpro.modules.models import Section, Module, Chapter, Topic
55

66

77
class ModuleAdmin(OrderedModelAdmin):
@@ -16,6 +16,11 @@ class ChapterAdmin(OrderedModelAdmin):
1616
list_display = 'title slug section order move_up_down_links'.split()
1717

1818

19+
class TopicAdmin(OrderedModelAdmin):
20+
list_display = 'title slug chapter order move_up_down_links'.split()
21+
22+
1923
admin.site.register(Module, ModuleAdmin)
2024
admin.site.register(Section, SectionAdmin)
2125
admin.site.register(Chapter, ChapterAdmin)
26+
admin.site.register(Topic, TopicAdmin)

pythonpro/modules/facade.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from django.db.models import Prefetch
22

3-
from pythonpro.modules.models import Section as _Section, Module as _Module, Chapter as _Chapter
3+
from pythonpro.modules.models import (Section as _Section, Module as _Module, Chapter as _Chapter, Topic as _Topic)
44

55

66
def get_all_modules():
@@ -11,7 +11,7 @@ def get_all_modules():
1111
return tuple(_Module.objects.order_by('order'))
1212

1313

14-
def get_module_with_sections_and_chapters(slug):
14+
def get_module_with_contents(slug):
1515
"""
1616
Search for a module with respective sections and chapters
1717
:param slug: module's slug
@@ -32,7 +32,7 @@ def get_module_with_sections_and_chapters(slug):
3232
).get()
3333

3434

35-
def get_section_with_module_and_chapters(slug):
35+
def get_section_with_contents(slug):
3636
"""
3737
Search for a section with respective module and chapters
3838
:param slug: section's slug
@@ -49,8 +49,24 @@ def get_section_with_module_and_chapters(slug):
4949

5050
def get_chapter_with_contents(slug):
5151
"""
52-
Search for a chapter respective to slug with it's module and section
52+
Search for a chapter respective to slug with it's module, section and topics
5353
:param slug: chapter's slug
5454
:return: Chapter
5555
"""
56-
return _Chapter.objects.filter(slug=slug).select_related('section').select_related('section__module').get()
56+
return _Chapter.objects.filter(slug=slug).select_related('section').select_related(
57+
'section__module').prefetch_related(
58+
Prefetch(
59+
'topic_set',
60+
queryset=_Topic.objects.order_by('order'),
61+
to_attr='topics'
62+
)).get()
63+
64+
65+
def get_topic_with_contents(slug):
66+
"""
67+
Search for a topic respective to slug with it's module, section anc chapter
68+
:param slug: topic's slug
69+
:return: Topic
70+
"""
71+
return _Topic.objects.filter(slug=slug).select_related('chapter').select_related('chapter__section').select_related(
72+
'chapter__section__module').get()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"model": "modules.topic", "pk": 1, "fields": {"order": 0, "title": "Curso Python Pro", "description": "V\u00eddeo explicando como funciona o curso Python Pro.", "slug": "curso-python-pro", "chapter": 1, "vimeo_id": "258681672"}}]
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Generated by Django 2.0.3 on 2018-03-18 16:33
2+
3+
from django.db import migrations, models
4+
import django.db.models.deletion
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('modules', '0006_chapter'),
11+
]
12+
13+
operations = [
14+
migrations.CreateModel(
15+
name='Topic',
16+
fields=[
17+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18+
('order', models.PositiveIntegerField(db_index=True, editable=False)),
19+
('title', models.CharField(max_length=50)),
20+
('description', models.TextField()),
21+
('slug', models.SlugField(unique=True)),
22+
('vimeo_id', models.CharField(max_length=11)),
23+
('chapter', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='modules.Chapter')),
24+
],
25+
options={
26+
'ordering': ['chapter', 'order'],
27+
},
28+
),
29+
]

pythonpro/modules/models.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,18 @@ def get_absolute_url(self):
8383

8484
def parent(self):
8585
return self.section
86+
87+
88+
class Topic(Content):
89+
chapter = models.ForeignKey('Chapter', on_delete=models.CASCADE)
90+
vimeo_id = models.CharField(max_length=11, db_index=False)
91+
order_with_respect_to = 'chapter'
92+
93+
class Meta:
94+
ordering = ['chapter', 'order']
95+
96+
def get_absolute_url(self):
97+
return reverse('topics:detail', kwargs={'slug': self.slug})
98+
99+
def parent(self):
100+
return self.chapter

pythonpro/modules/modules_views.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
from django.shortcuts import render
33

44
# Create your views here.
5-
from pythonpro.modules.facade import get_module_with_sections_and_chapters, get_all_modules
5+
from pythonpro.modules.facade import get_module_with_contents, get_all_modules
66

77

88
@login_required
99
def detail(request, slug):
10-
module = get_module_with_sections_and_chapters(slug)
10+
module = get_module_with_contents(slug)
1111
return render(request, 'modules/module_detail.html', {'module': module})
1212

1313

pythonpro/modules/sections_views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44

55

66
def detail(request, slug):
7-
ctx = {'section': facade.get_section_with_module_and_chapters(slug=slug)}
7+
ctx = {'section': facade.get_section_with_contents(slug=slug)}
88
return render(request, 'sections/section_detail.html', ctx)

pythonpro/modules/templates/chapters/chapter_detail.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ <h1 class="mt-4 mb-3">{{ chapter.title }}</h1>
2525
<li>{{ chapter.description }}</li>
2626
</ul>
2727
</dd>
28+
<dt>Tópicos</dt>
29+
<dd>
30+
<ol>
31+
{% for topic in chapter.topics %}
32+
<li><a href="{{ topic.get_absolute_url }}">{{ topic.title }}</a></li>
33+
{% empty %}
34+
<li>Nenhum Tópico definido ainda</li>
35+
{% endfor %}
36+
</ol>
37+
</dd>
2838
</div>
2939
</div>
3040
</div>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{% extends 'core/base.html' %}
2+
{% load static %}
3+
4+
{% block title %}{{ topic.title }}{% endblock %}
5+
6+
{% block body %}
7+
<nav aria-label="breadcrumb">
8+
<ol class="breadcrumb">
9+
{% for title, url in topic.breadcrumb %}
10+
{% if not forloop.last %}
11+
<li class="breadcrumb-item"><a href="{{ url }}">{{ title }}</a></li>
12+
{% else %}
13+
<li class="breadcrumb-item active" aria-current="page">{{ title }}</li>
14+
{% endif %}
15+
{% endfor %}
16+
</ol>
17+
</nav>
18+
<div class="container">
19+
<div class="row">
20+
<div class="col">
21+
<h1 class="mt-4 mb-3">{{ topic.title }}</h1>
22+
<p>{{ topic.description }}</p>
23+
<div class="embed-container">
24+
<iframe src="https://player.vimeo.com/video/{{ topic.vimeo_id }}" width="640" height="360" frameborder="0"
25+
webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
26+
</div>
27+
</div>
28+
</div>
29+
</div>
30+
{% endblock body %}

pythonpro/modules/tests/test_chapters_view.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ def test_breadcrumb_section(resp, section):
6666
resp,
6767
f'<li class="breadcrumb-item"><a href="{section.get_absolute_url()}">{section.title}</a></li>'
6868
)
69-
#
70-
#
71-
# def test_breadcrumb_current(resp, section):
72-
# dj_assert_contains(
73-
# resp,
74-
# f'<li class="breadcrumb-item active" aria-current="page">{section.title}</li>'
75-
# )
69+
70+
71+
def test_breadcrumb_current(resp, chapter):
72+
dj_assert_contains(
73+
resp,
74+
f'<li class="breadcrumb-item active" aria-current="page">{chapter.title}</li>'
75+
)

0 commit comments

Comments
 (0)