Aula 15 – Loja Online – Django – URLs dos Produtos
Aula 15 – Loja Online – Django – URLs dos Produtos
Loja Virtual – Ecommerce – Django – URLs dos Produtos
Estamos prestes a terminar com a base da app produtos, isto é, do componente produto.
![Modelo base - Base Template Modelo base - URLs dos Produtos](https://www.codigofluente.com.br/wp-content/uploads/2019/01/aula-11-loja-online-ecommerce-dj.jpg)
Modelo base – URLs dos Produtos
Voltar para página principal do blog
Todas as aulas desse curso
Aula 14 Aula 16
Para baixar o código como está até agora, acesse o link abaixo:
https://github.com/toticavalcanti/django_ecommerce/tree/product_urls
Dêem um joinha 👍 na página do Código Fluente no Facebook
https://www.facebook.com/Codigofluente-338485370069035/
Vou deixar meu link de referidos na digitalocean pra vocês.
Quem se cadastrar por esse link, ganha $100.00 dólares de crédito na digitalocean:
Digital Ocean
Esse outro link é da one.com:
One.com
Seguindo!
Não fizemos as outras partes do crud, atualizar e excluir, essas partes do crud a gente pode fazer como administrador no Django, não precisamos nos preocupar com isso.
Os usuários não vão poder editar um produto, muito menos excluir um produto do banco.
A gente focou muito na view dos produtos, porque isso é o mais importante, nós queremos ter certeza de que os usuários possam ver os produtos.
Vamos desafogar um pouco nosso src/e_commerce/urls.py criando um outro urls.py, o urls.py para o product, ou seja, src/product/urls.py.
Depois criaremos no nosso model dentro da class Product, o método get_absolute_url(), que irá retornar a url de um produto.
Então vamos lá!
Primeiro vamos organizar melhor as nossas urls, vamos dividir em dois arquivos:
- src/e_commerce/urls.py
- src/product/urls.py
Crie o src/product/urls.py com o seguinte conteúdo:
from django.urls import path
from .views import (
ProductListView,
ProductDetailSlugView,
)
urlpatterns = [
path('', ProductListView.as_view()),
path('<slug:slug>/', ProductDetailSlugView.as_view())
]
Atualize o src/e_commerce/urls.py:
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
from .views import (home_page,
about_page,
contact_page,
login_page,
register_page
)
urlpatterns = [
path('', home_page),
path('about/', about_page),
path('contact/', contact_page),
path('login/', login_page),
path('register/', register_page),
path('products/', include("products.urls")),
path('admin/', admin.site.urls),
]
if settings.DEBUG:
urlpatterns = urlpatterns + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns = urlpatterns + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Dessa forma nossas URLs ficaram bem melhores, veja que fizemos o import do include, e com ele importamos o urls.py do products, ou seja, src/product/urls.py para dentro do src/e_commerce/urls.py.
Nossas URLs melhoraram bastante.
Note que não temos mais as urls detail view, não vamos mais precisar delas.
Elas nos mostravam os detalhes dos produtos baseado no id de um produto na URL, o que não é interessante pois expõe o id daquele produto no banco de dados, além de não ser amigável para o usuário, prejudicando o SEO.
Quem vai mostrar os detalhes de cada produto agora é a nossa CBV (Class Based View) ProductDetailSlugView, construída na aula passada.
Ela mostra os detalhes do produto baseado no slug do produto, mostrando na url o slug do produto e não seu id.
Vamos criar o método get_absolute_url no nosso modelo produto, então em src/products/models.py, acrescente o método que tá em laranja, o get_absolute_url:
import random
import os
from django.db import models
from django.db.models.signals import pre_save, post_save
from .utils import unique_slug_generator
def get_filename_ext(filepath):
base_name = os.path.basename(filepath)
name, ext = os.path.splitext(base_name)
return name, ext
def upload_image_path(instance, filename):
new_filename = random.randint(1, 3910209312)
name, ext = get_filename_ext(filename)
final_filename = '{new_filename}{ext}'.format(new_filename = new_filename, ext = ext) #old format
#final_filename = f"{new_filename}{ext}" #syntax to python 3.6 and up
return "products/{new_filename}/{final_filename}".format(
new_filename = new_filename,
final_filename = final_filename
)
#return f"products/{new_filename}/{new_filename}" #syntax to python 3.6 and up
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):
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=39.99)
image = models.ImageField(upload_to = upload_image_path, null = True, blank = True)
featured = models.BooleanField(default = False)
active = models.BooleanField(default = True)
objects = ProductManager()
def get_absolute_url(self):
return "/products/{slug}/".format(slug = self.slug)
def __str__(self):
return self.title
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)
O get_absolute_url vai devolver a string com o slug do produto consultado, para montar a url.
Agora vamos alterar o template inserindo a tag <a> com o hrefs apontando para a url do produto.
Então modifique o src/products/templates/products/list.html:
{% for obj in object_list %}
<a href='{{ obj.get_absolute_url }}'>{{ obj.title }}</a><br/>
{% endfor%}
Agora os usuários poderão navegar pelos produtos clicando nos links.
O get_absolute_url é uma convenção do Django, é necessário para usar a função reverse() que iremos falar depois, mas, só pra dá uma leve pincelada, a principal vantagem do reverse() é que você não precisa codificar rotas no código.
O reverse () é usado para aderir ao princípio DRY (don’t repeat yourself), ou seja, se você alterar uma url no futuro, poderá fazer referência a essa url usando reverse (nome_da_url).
Usar o get_absolute_url é mais conveniente e vai facilitar a nossa vida, se precisar mudar qualquer URL basta ir a um lugar para fazer isso.
As convenções do django não são obrigatórias, mas, são importantes, pois são baseadas no que desenvolvedores experientes consideram ser o melhor caminho para fazer determinadas coisas.
É isso programadoras e programadores, vou ficando por aqui.
Na próxima aula, vamos melhorar nossos HTMLs.
Aula 14 Aula 16
Todas as aulas desse curso
Voltar para página principal do blog
Dêem um joinha 👍 na página do Código Fluente no Facebook
https://www.facebook.com/Codigofluente-338485370069035/
Vou deixar meu link de referidos na digitalocean pra vocês.
Quem se cadastrar por esse link, ganha $100.00 dólares de crédito na digitalocean:
Digital Ocean
Esse outro link é da one.com:
One.com
Para baixar o código como está até agora, acesse o link abaixo:
https://github.com/toticavalcanti/django_ecommerce/tree/product_urls
Obrigado, até a próxima e bons estudos. 😉