Skip to content

Commit

Permalink
Speaker #104
Browse files Browse the repository at this point in the history
  • Loading branch information
matheuspdf committed Jun 5, 2024
1 parent 9b3d36b commit ae4bc3b
Show file tree
Hide file tree
Showing 13 changed files with 264 additions and 10 deletions.
21 changes: 21 additions & 0 deletions eventex/core/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from eventex.core.models import Speaker
from django.contrib import admin
from django.utils.html import format_html


class SpeakerModelAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('name',)}
list_display = ['name', 'photo_img', 'website_link']

def website_link(self, obj):
return format_html('<a href="{0}">{0}</a>', obj.website)

website_link.sort_description = 'website'

def photo_img(self, obj):
return format_html('<img width="32px" src="{}" />', obj.photo)

photo_img.short_description = 'foto'


admin.site.register(Speaker, SpeakerModelAdmin)
24 changes: 24 additions & 0 deletions eventex/core/fixtures/keynotes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[
{
"model": "core.speaker",
"pk": 1,
"fields": {
"name": "Grace Hopper",
"slug": "grace-hopper",
"website": "https://pt.wikipedia.org/wiki/Grace_Hopper",
"photo": "https://www.timeforkids.com/wp-content/uploads/2020/08/Grace_003.jpg?w=926",
"description": "Programadora e almirante.\r\nInventora do compilador, criadora da linguagem de programação Flow-Matic que serviu de base para a linguagem COBOL permitindo a popularização das aplicações comerciais."
}
},
{
"model": "core.speaker",
"pk": 2,
"fields": {
"name": "Alan Turing",
"slug": "alan-turing",
"website": "https://pt.wikipedia.org/wiki/Alan_Turing",
"photo": "https://cdn.britannica.com/81/191581-050-8C0A8CD3/Alan-Turing.jpg",
"description": "Matemático e decifrador de códigos.\r\nInventou o computador moderno, formalizou matematicamente o que é um algorítimo e de quebra salvou o mundo como conhecemos ao destroçar a criptografia nazista."
}
}
]
32 changes: 32 additions & 0 deletions eventex/core/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Generated by Django 5.0.3 on 2024-06-01 23:18

from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = []

operations = [
migrations.CreateModel(
name="Speaker",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=255)),
("slug", models.SlugField()),
("website", models.URLField()),
("photo", models.URLField()),
("description", models.TextField()),
],
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Generated by Django 5.0.3 on 2024-06-05 00:41

from django.db import migrations, models


class Migration(migrations.Migration):

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

operations = [
migrations.AlterModelOptions(
name="speaker",
options={
"verbose_name": "palestrante",
"verbose_name_plural": "palestrantes",
},
),
migrations.AlterField(
model_name="speaker",
name="description",
field=models.TextField(blank=True, verbose_name="descrição"),
),
migrations.AlterField(
model_name="speaker",
name="name",
field=models.CharField(max_length=255, verbose_name="nome"),
),
migrations.AlterField(
model_name="speaker",
name="photo",
field=models.URLField(verbose_name="foto"),
),
migrations.AlterField(
model_name="speaker",
name="slug",
field=models.SlugField(verbose_name="slug"),
),
migrations.AlterField(
model_name="speaker",
name="website",
field=models.URLField(blank=True, verbose_name="website"),
),
]
20 changes: 20 additions & 0 deletions eventex/core/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from django.db import models
from django.shortcuts import resolve_url as r


class Speaker(models.Model):
name = models.CharField('nome', max_length=255)
slug = models.SlugField('slug')
website = models.URLField('website', blank=True)
photo = models.URLField('foto')
description = models.TextField('descrição', blank=True)

class Meta:
verbose_name = 'palestrante'
verbose_name_plural = 'palestrantes'

def __str__(self):
return self.name

def get_absolute_url(self):
return r('speaker_detail', slug=self.slug)
6 changes: 6 additions & 0 deletions eventex/core/static/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -369,4 +369,10 @@ section header h2 {
border-radius: 100%;
}

.speakers img.photo{
float: left;
padding-right: 40px;
}


/* Fim Customização */
16 changes: 16 additions & 0 deletions eventex/core/templates/core/speaker_detail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% extends 'base.html' %}

{% block content %}
<!-- OVERVIEW -->
<section>
<div class="speakers content row padding-bottom-3 desktop-8 container">
<h2>
<a href="{{ speaker.site }}">{{ speaker.name }}</a>
</h2>
<img class="photo" src="{{ speaker.photo }}">
<p>
{{ speaker.description|linebreaks }}
</p>
</div>
</section>
{% endblock content %}
8 changes: 6 additions & 2 deletions eventex/core/templates/index.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% load static %}
<!DOCTYPE html>
<html>
<html xmlns="http://www.w3.org/1999/html">
<head>
<title>Eventex - O maior encontro hacker do mundo!</title>

Expand Down Expand Up @@ -62,7 +62,11 @@ <h2>Palestrantes Convidados</h2>
{% for speaker in speakers %}
<div class="desktop-4">
<img src="{{ speaker.photo }}">
<h4>{{ speaker.name }}</h4>
<h4>
<a href="{{ speaker.get_absolute_url }}">
{{ speaker.name }}
</a>
</h4>
</div>
{% endfor %}
</div>
Expand Down
32 changes: 32 additions & 0 deletions eventex/core/tests/test_model_speaker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from django.test import TestCase
from eventex.core.models import Speaker
from django.shortcuts import resolve_url as r


class SpeakerModelTest(TestCase):
def setUp(self):
self.speaker = Speaker.objects.create(
name='Grace Hopper',
slug='grace-hopper',
photo='https://www.timeforkids.com/wp-content/uploads/2020/08/Grace_003.jpg?w=926',
website='https://www.timeforkids.com/wp-content/uploads/2020/08/Grace_003.jpg?w=926',
description='Programadora e almirante'
)

def test_create(self):
self.assertTrue(Speaker.objects.exists())

def test_description_can_be_blank(self):
field = Speaker._meta.get_field('description')
self.assertTrue(field.blank)

def test_website_can_be_blank(self):
field = Speaker._meta.get_field('website')
self.assertTrue(field.blank)

def test_str(self):
self.assertEqual('Grace Hopper', str(self.speaker))

def test_get_absolute_url(self):
url = r('speaker_detail', slug=self.speaker.slug)
self.assertEqual(url, self.speaker.get_absolute_url())
4 changes: 4 additions & 0 deletions eventex/core/tests/test_view_home.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@


class HomeTest(TestCase):
fixtures = ['keynotes.json']

def setUp(self):
self.response = self.client.get(r('home'))

Expand All @@ -27,8 +29,10 @@ def test_subscription_link(self):
def test_speakers(self):
"""Must show keynote speakers"""
contents = [
'href="{}'.format(r('speaker_detail', slug='grace-hopper')),
'Grace Hopper',
'https://www.timeforkids.com/wp-content/uploads/2020/08/Grace_003.jpg?w=926',
'href="{}'.format(r('speaker_detail', slug='alan-turing')),
'Alan Turing',
'https://cdn.britannica.com/81/191581-050-8C0A8CD3/Alan-Turing.jpg',
]
Expand Down
45 changes: 45 additions & 0 deletions eventex/core/tests/test_view_speaker_detail.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from django.test import TestCase
from django.shortcuts import resolve_url as r
from eventex.core.models import Speaker


class SpeakerDetailGet(TestCase):
def setUp(self):
Speaker.objects.create(
name='Grace Hopper',
slug='grace-hopper',
photo='https://www.timeforkids.com/wp-content/uploads/2020/08/Grace_003.jpg?w=926',
website='https://www.timeforkids.com/wp-content/uploads/2020/08/Grace_003.jpg?w=926',
description='Programadora e almirante'
)
self.resp = self.client.get(r('speaker_detail', slug='grace-hopper'))

def test_get(self):
"""GET should return status 200"""
self.assertEqual(200, self.resp.status_code)

def test_template(self):
self.assertTemplateUsed(self.resp, 'core/speaker_detail.html')

def test_html(self):
contents = [
'Grace Hopper',
'Programadora e almirante',
'https://www.timeforkids.com/wp-content/uploads/2020/08/Grace_003.jpg?w=926',
'https://www.timeforkids.com/wp-content/uploads/2020/08/Grace_003.jpg?w=926',
]

for expected in contents:
with self.subTest():
self.assertContains(self.resp, expected)

def test_context(self):
"""Speaker must be in context"""
speaker = self.resp.context['speaker']
self.assertIsInstance(speaker, Speaker)


class SpeakerDetailNotFound(TestCase):
def test_not_found(self):
response = self.client.get(r('speaker_detail', slug='not-found'))
self.assertEqual(404, response.status_code)
15 changes: 9 additions & 6 deletions eventex/core/views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from django.shortcuts import render
from django.shortcuts import render, get_object_or_404

from eventex.core.models import Speaker

def home(request):
speakers = [
{'name': 'Grace Hopper', 'photo': 'https://www.timeforkids.com/wp-content/uploads/2020/08/Grace_003.jpg?w=926'},
{'name': 'Alan Turing', 'photo': 'https://cdn.britannica.com/81/191581-050-8C0A8CD3/Alan-Turing.jpg'},

]
def home(request):
speakers = Speaker.objects.all()
return render(request, 'index.html', {'speakers': speakers})


def speaker_detail(request, slug):
speaker = get_object_or_404(Speaker, slug=slug)
return render(request, 'core/speaker_detail.html', {'speaker': speaker})
6 changes: 4 additions & 2 deletions eventex/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
"""
from django.contrib import admin
from django.urls import path, include
import eventex.core.views
from eventex.core.views import home, speaker_detail


urlpatterns = [
path('', eventex.core.views.home, name='home'),
path('', home, name='home'),
path('inscricao/', include('eventex.subscriptions.urls')),
path('palestrantes/<slug:slug>/', speaker_detail, name='speaker_detail'),
path('admin/', admin.site.urls),
]

0 comments on commit ae4bc3b

Please sign in to comment.