Aula 23 - Loja Online - Django - Template Filters
Se gostarem do conteúdo dêem um joinha 👍 na página do Código Fluente no
Facebook
Esse é o link do código fluente no Pinterest
Meus links de afiliados:
Dicas de livros relacionados:
Nessa aula vamos falar sobre as template filter tags do Django.
Vamos começar vendo um
template filter tag chamado
truncatewords, isto é, palavras truncadas.
O que ele faz é diminuir a quantidade texto mostrada.
Por exemplo, podemos ter a descrição de um produto com um texto bem longo, mas, queremos que na listagem dos produtos apareça apenas parte da descrição, então, podemos usar o
truncatewords.
Só para ilustrar, usaremos o
lorem texto ipsum apenas para copiar um texto longo
fake de descrição para um produto, um texto fictício.
Agora temos um produto com uma descrição super longa.
Você vai ver que fica muito estranho um texto de descrição bem longa de um produto sendo mostrado na listagens do produto.
Poderíamos perfeitamente usar algo como
JavaScript ou
CSS para esconder o texto.
Mas, o
truncatewords faz isso de forma menos verbosa, ou seja, escrevemos menos, é bem mais direto, simples e fácil, além de utilizar um recurso nativo do
django.
Crie um produto
fake utilizando o
https://br.lipsum.com/ para gerar um texto de descrição
dummy, falso, só pra testar mesmo.
Copie o texto gerado na descrição desse novo produto, dê o nome que quiser a ele.
Salve o produto.
Agora abra o django_ecommerce/products/templates/products/snippets/card.html
Na classe card-text substitua o texto pelo que tá em laranja no código abaixo.
<div class="card" style="width: 18rem;">
{% if instance.image %}
<a href="{{ instance.get_absolute_url }}">
<img src="{{ instance.image.url }}" class="card-img-top" alt="{{ instance.title }} logo">
</a>
{% endif %}
<div class="card-body">
<h5 class="card-title">{{ instance.title }}</h5>
<p class="card-text">{{ instance.description }}</p>
<a href="{{ instance.get_absolute_url }}" class="btn btn-primary">Detalhe</a>
<a href="{% url 'products:detail' slug=instance.slug %}" class="btn btn-warning">Atalho para a URL</a>
</div>
</div>
Veja que ele mostra toda a descrição longa desse novo produto.
Isso não é legal, então vamos usar o truncatewords
Novamente na classe card-text coloque que tá em laranja no código abaixo.
<div class="card" style="width: 18rem;">
{% if instance.image %}
<a href="{{ instance.get_absolute_url }}">
<img src="{{ instance.image.url }}" class="card-img-top" alt="{{ instance.title }} logo">
</a>
{% endif %}
<div class="card-body">
<h5 class="card-title">{{ instance.title }}</h5>
<p class="card-text">{{ instance.description|truncatewords:14 }}</p>
<a href="{{ instance.get_absolute_url }}" class="btn btn-primary">Detalhe</a>
<a href="{% url 'products:detail' slug=instance.slug %}" class="btn btn-warning">Atalho para a URL</a>
</div>
</div>
Clique na
view de detalhe desse novo
produto(Lorem Ipsum).
Você verá o texto completo da descrição, na página desse produto em específico.
Perceba que o texto tá totalmente sem formatação.
Então, para melhorar isso, usaremos outra
template filter tags do
Django, a
linebreaks.
Template filter tags linebreaks
Abra o django_ecommerce/products/templates/product/detail.html e coloque o conteúdo que tá em laranja.
{% extends "base.html" %}
{% block content %}
{{ object.title }} <br/>
{{ object.description|linebreaks }} <br/>
{% if object.image %}
<img src='{{ object.image.url }}' class='img-fluid'/>
{% endif %}
{% endblock content %}
Veja que o
linebreaks construiu parágrafos para o texto de descrição.
Template filter tags title
Vamos colocar as
divs container,
row e
col no
detail.html para formatação do texto com o
bootstrap.
Vamos usar também o
template filter tags title.
O
filter tags title converte uma
string em
titlecase, fazendo com que as palavras iniciem com um caractere maiúsculo e os demais caracteres minúsculos.
Se o valor for a string: "
minha PRIMEIRA postagem"
A saída será: "
Minha Primeira Postagem".
Então, em django_ecommerce/products/templates/product/detail.html e coloque o conteúdo que tá em laranja.
{% extends "base.html" %}
{% block content %}
<div class='container'>
<div class='row'>
<div class='col'>
<h1>{{ object.title }}</h1>
<h3>{{ "Um título qualquer"|title }}</h3>
{{ object.description|linebreaks }} <br/>
{% if object.image %}
<img src='{{ object.image.url }}' class='img-fluid'/>
{% endif %}
</div>
</div>
</div>
{% endblock content %}
Agora em django_ecommerce/products/models.py crie o campo timestamp.
from django.db import models
from .utils import unique_slug_generator
from django.db.models.signals import pre_save
from django.urls import reverse
#Custom queryset
class ProductQuerySet(models.query.QuerySet):
def active(self):
return self.filter(active = True)
def featured(self):
return self.filter(featured = True, active = True)
class ProductManager(models.Manager):
def get_queryset(self):
return ProductQuerySet(self.model, using = self._db)
def all(self):
return self.get_queryset().active()
def featured(self):
#self.get_queryset().filter(featured = True)
return self.get_queryset().featured()
def get_by_id(self, id):
qs = self.get_queryset().filter(id = id)
if qs.count() == 1:
return qs.first()
return None
# Create your models here.
class Product(models.Model): #product_category
title = models.CharField(max_length=120)
slug = models.SlugField(blank = True, unique = True)
description = models.TextField()
price = models.DecimalField(decimal_places=2, max_digits=20, default=100.00)
image = models.FileField(upload_to = 'products/', null = True, blank = True)
featured = models.BooleanField(default = False)
active = models.BooleanField(default = True)
timestamp = models.DateTimeField(auto_now_add = True)
objects = ProductManager()
def get_absolute_url(self):
#return "/products/{slug}/".format(slug = self.slug)
return reverse("products:detail", kwargs={"slug": self.slug})
#python 3
def __str__(self):
return self.title
#python 2
def __unicode__(self):
return self.title
def product_pre_save_receiver(sender, instance, *args, **kwargs):
if not instance.slug:
instance.slug = unique_slug_generator(instance)
pre_save.connect(product_pre_save_receiver, sender = Product)
Rode:
python manage.py makemigrations
Ele vai dar duas opções, escolha 1.
No prompt, digite:
timezone.now
Execute:
python manage.py migrate
Agora em django_ecommerce/products/templates/product/detail.html, coloque o conteúdo que tá em laranja.
{% extends "base.html" %}
{% block content %}
<div class='container'>
<div class='row'>
<div class='col'>
<h1>{{ object.title }}</h1>
{{ object.timestamp|timesince }} atrás
<h3>{{ "Um título qualquer"|title }}</h3>
{{ object.description|linebreaks }} <br/>
{% if object.image %}
<img src='{{ object.image.url }}' class='img-fluid'/>
{% endif %}
</div>
</div>
</div>
{% endblock content %}
Ou qualquer outro produto já cadastrado.
É isso, por hora ficamos por aqui.
Se gostarem do conteúdo dêem um joinha 👍 na página do Código Fluente no
Facebook
Link do código fluente no Pinterest
Novamente deixo meus link de afiliados:
Obrigado, até a próxima e bons estudos. ;)