Skip to content

Commit

Permalink
Criação de App de Módulos de aulas close #39 (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
matheuspdf authored Oct 9, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 4ea79df commit f608d29
Showing 26 changed files with 589 additions and 250 deletions.
2 changes: 2 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@ django-s3-folder-storage = "*"
collectfast = "*"
django-debug-toolbar = "*"
sentry-sdk = "*"
django-ordered-model = "*"
python-slugify = "*"

[dev-packages]
flake8 = "*"
505 changes: 283 additions & 222 deletions Pipfile.lock

Large diffs are not rendered by default.

Empty file added pypro/base/__init__.py
Empty file.
65 changes: 39 additions & 26 deletions pypro/base/templates/base/base.html
Original file line number Diff line number Diff line change
@@ -1,38 +1,51 @@
<!DOCTYPE html>
{% load static %}
<html lang="pt-br">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}Python Pro{% endblock title %}</title>
<meta name="description" content="{% block description %}Página do curso Python Pro{% endblock description %}">
<meta name="author" content="Matheus Lopes">
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1" name="viewport">
<title>{% block title %}Python Pro{% endblock title %}</title>
<meta content="{% block description %}Página do curso Python Pro{% endblock description %}" name="description">
<meta content="Matheus Lopes" name="author">

<link rel="icon" type="image/png" href="{% static 'img/favicon.png' %}" />
<link href="{% static 'img/favicon.png' %}" rel="icon" type="image/png"/>

<link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
<link href="{% static 'css/style.css' %}" rel="stylesheet">
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script src="{% static 'js/scripts.js' %}"></script>
<link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
<link href="{% static 'css/style.css' %}" rel="stylesheet">
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script src="{% static 'js/scripts.js' %}"></script>

</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="{% url 'base:home' %}">Python Pro</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
</ul>
</div>
</nav>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="{% url 'base:home' %}">Python Pro</a>
<button aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation" class="navbar-toggler"
data-target="#navbarSupportedContent" data-toggle="collapse" type="button">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item dropdown">
<a aria-expanded="false" aria-haspopup="true" class="nav-link dropdown-toggle" data-toggle="dropdown" href="#"
id="navbarDropdown" role="button">
Módulos
</a>
<div aria-labelledby="navbarDropdown" class="dropdown-menu">
{% for modulo in MODULOS %}
<a class="dropdown-item" href="{{modulo.get_absolute_url}}">{{modulo.titulo}}</a>
<div class="dropdown-divider"></div>
{% endfor %}
</div>
</li>
</ul>
</div>
</nav>

{% block body %} {% endblock body %}

{% include 'base/footer.html' with contato_email='[email protected]' only %}

</body>
</body>
</html>
2 changes: 1 addition & 1 deletion pypro/base/tests/test_home.py
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@


@pytest.fixture
def resp(client):
def resp(client, db):
resp = client.get(reverse('base:home'))
return resp

2 changes: 1 addition & 1 deletion pypro/base/views.py
Original file line number Diff line number Diff line change
@@ -3,4 +3,4 @@


def home(request):
return render(request, 'base/home.html',)
return render(request, 'base/home.html', {})
Empty file added pypro/modulos/__init__.py
Empty file.
10 changes: 10 additions & 0 deletions pypro/modulos/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.contrib import admin
from ordered_model.admin import OrderedModelAdmin

from pypro.modulos.models import Modulo


@admin.register(Modulo)
class ModuloAdmin(OrderedModelAdmin):
list_display = ('titulo', 'publico', 'move_up_down_links')
prepopulated_fields = {'slug': ('titulo',)}
6 changes: 6 additions & 0 deletions pypro/modulos/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class ModulosConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "pypro.modulos"
5 changes: 5 additions & 0 deletions pypro/modulos/context_processors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from pypro.modulos import facade


def listar_modulos(request):
return {'MODULOS': facade.listar_modulos_ordenados()}
16 changes: 16 additions & 0 deletions pypro/modulos/facade.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from typing import List

from pypro.modulos.models import Modulo


def listar_modulos_ordenados() -> List[Modulo]:
"""
Lista módulos ordenados por títulos
:return:
"""
return list(Modulo.objects.order_by('order').all())


def encontrar_modulo(slug: str) -> Modulo:
return Modulo.objects.get(slug=slug)
40 changes: 40 additions & 0 deletions pypro/modulos/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Generated by Django 4.2.6 on 2023-10-07 13:42

from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = []

operations = [
migrations.CreateModel(
name="Modulo",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"order",
models.PositiveIntegerField(
db_index=True, editable=False, verbose_name="order"
),
),
("titulo", models.CharField(max_length=64)),
("publico", models.TextField()),
("descricao", models.TextField()),
],
options={
"ordering": ("order",),
"abstract": False,
},
),
]
18 changes: 18 additions & 0 deletions pypro/modulos/migrations/0002_modulo_slug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.6 on 2023-10-07 15:20

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("modulos", "0001_initial"),
]

operations = [
migrations.AddField(
model_name="modulo",
name="slug",
field=models.SlugField(null=True),
),
]
21 changes: 21 additions & 0 deletions pypro/modulos/migrations/0003_populando_slug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Generated by Django 4.2.6 on 2023-10-07 15:25

from django.db import migrations
from django.utils.text import slugify


def popular_slug(apps, schema_editor):
Modulo = apps.get_model('modulos', 'Modulo')
for modulo in Modulo.objects.all():
modulo.slug = slugify(modulo.titulo)
modulo.save()


class Migration(migrations.Migration):
dependencies = [
("modulos", "0002_modulo_slug"),
]

operations = [
migrations.RunPython(popular_slug)
]
18 changes: 18 additions & 0 deletions pypro/modulos/migrations/0004_slug_unico_e_nao_nulo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.6 on 2023-10-07 15:33

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("modulos", "0003_populando_slug"),
]

operations = [
migrations.AlterField(
model_name="modulo",
name="slug",
field=models.SlugField(unique=True),
),
]
Empty file.
19 changes: 19 additions & 0 deletions pypro/modulos/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from django.db import models
from django.urls.base import reverse
from ordered_model.models import OrderedModel


class Modulo(OrderedModel):
titulo = models.CharField(max_length=64)
publico = models.TextField()
descricao = models.TextField()
slug = models.SlugField(unique=True)

class Meta(OrderedModel.Meta):
pass

def __str__(self):
return self.titulo

def get_absolute_url(self):
return reverse('modulos:detalhe', kwargs={'slug': self.slug})
20 changes: 20 additions & 0 deletions pypro/modulos/templates/modulos/modulo_detalhe.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% extends 'base/base.html' %}
{% load static %}
{% block title %}{{modulo.titulo}}{% endblock title %}
{% block description %}Página com detalhes do módulo {{modulo.titulo}}{% endblock description %}
{% block body %}
<div class="container">
<div class="row">
<div class="col-md-12">
<h1 class="mt-4 mb-3">{{ modulo.titulo }}</h1>
<dl>
<dt>Público</dt>
<dd>{{ modulo.publico }}</dd>
<dt>Descrição</dt>
<dd>{{ modulo.descricao }}</dd>
</dl>
</div>
</div>
</div>
{% endblock body %}

Empty file added pypro/modulos/tests/__init__.py
Empty file.
27 changes: 27 additions & 0 deletions pypro/modulos/tests/test_aba_de_modulos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import pytest
from django.urls import reverse
from pypro.django_assertions import assert_contains
from model_mommy import mommy

from pypro.modulos.models import Modulo


@pytest.fixture
def modulos(db):
return mommy.make(Modulo, 2)


@pytest.fixture
def resp(client, modulos):
resp = client.get(reverse('base:home'))
return resp


def test_titulos_dos_modulos(resp, modulos):
for modulo in modulos:
assert_contains(resp, modulo.titulo)


def test_link_dos_modulos(resp, modulos):
for modulo in modulos:
assert_contains(resp, modulo.get_absolute_url())
14 changes: 14 additions & 0 deletions pypro/modulos/tests/test_facade.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import pytest
from model_mommy import mommy

from pypro.modulos import facade
from pypro.modulos.models import Modulo


@pytest.fixture
def modulos(db):
return [mommy.make(Modulo, titulo=s) for s in 'Antes Depois'.split()]


def test_listar_modulos_ordenados(modulos):
assert list(sorted(modulos, key=lambda modulo: modulo.order)) == facade.listar_modulos_ordenados()
29 changes: 29 additions & 0 deletions pypro/modulos/tests/test_modulo_detalhe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import pytest
from django.urls import reverse
from pypro.django_assertions import assert_contains
from model_mommy import mommy

from pypro.modulos.models import Modulo


@pytest.fixture
def modulo(db):
return mommy.make(Modulo)


@pytest.fixture
def resp(client, modulo):
resp = client.get(reverse('modulos:detalhe', kwargs={'slug': modulo.slug}))
return resp


def test_titulo(resp, modulo: Modulo):
assert_contains(resp, modulo.titulo)


def test_descricao(resp, modulo: Modulo):
assert_contains(resp, modulo.descricao)


def test_publico(resp, modulo: Modulo):
assert_contains(resp, modulo.publico)
8 changes: 8 additions & 0 deletions pypro/modulos/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.urls import path

from pypro.modulos import views

app_name = 'modulos'
urlpatterns = [
path('<slug:slug>', views.detalhe, name='detalhe'),
]
8 changes: 8 additions & 0 deletions pypro/modulos/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.shortcuts import render

from pypro.modulos import facade


def detalhe(request, slug):
modulo = facade.encontrar_modulo(slug)
return render(request, 'modulos/modulo_detalhe.html', {'modulo': modulo})
3 changes: 3 additions & 0 deletions pypro/settings.py
Original file line number Diff line number Diff line change
@@ -47,6 +47,8 @@
'django.contrib.staticfiles',
'pypro.base',
'pypro.aperitivos',
'pypro.modulos',
'ordered_model',
]

MIDDLEWARE = [
@@ -71,6 +73,7 @@
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'pypro.modulos.context_processors.listar_modulos',
],
},
},
Loading

0 comments on commit f608d29

Please sign in to comment.