Aula 89 – Lidando com o Sinal do Objeto Visualizado
Aula 89 – Lidando com o Sinal do Objeto Visualizado

Loja Online – Django
Voltar para página principal do blog
Todas as aulas desse curso
Aula 88 Aula 90
Redes Sociais:
Meus links de afiliados:
Hostinger
Digital Ocean
One.com
Melhore seu NETWORKING
https://digitalinnovation.one/
Participe de comunidades de desenvolvedores:
Fiquem a vontade para me adicionar ao linkedin.
E também para me seguir no https://github.com/toticavalcanti.
Código final da aula:
https://github.com/toticavalcanti
Quer aprender python3 de graça e com certificado? Acesse então:
https://workover.com.br/python-codigo-fluente
Canais do Youtube
Toti
Lofi Music Zone Beats
Backing Track / Play-Along
Código Fluente
Putz!
Vocal Techniques and Exercises
PIX para doações

PIX Nubank
Aula 89 – Lidando com o Sinal do Objeto Visualizado
Agora vamos lidar com o sinal emitido pelo objeto visualizado.
Temos o mixin, temos o signal, que fizemos na aula passada, e portanto, uma forma de trabalhar com esses dados dos produtos visualizados.
Então bora lá!
Abra o models.py do analytics e faça as alterações indicadas abaixo em azul.
django_ecommerce/e_commerce/analytics/models.py
from django.conf import settings
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from .signals import object_viewed_signal
User = settings.AUTH_USER_MODEL
class ObjectViewed(models.Model):
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE) # specific user, instance.id
ip_address = models.CharField(max_length=220, blank=True, null=True)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) # Product, Order, Cart, Address...
object_id = models.PositiveIntegerField() # User id, Product id, Order id
content_object = GenericForeignKey('content_type', 'object_id')
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.content_object} viewed on {self.timestamp}"
class Meta:
ordering = ['-timestamp'] # most recent saved show up first
verbose_name = 'Object viewed'
verbose_name_plural = 'Objects viewed'
def object_viewed_receiver(sender, instance, request, *args, **kwargs):
print(sender)
print(instance)
print(request)
print(request.user)
object_viewed_signal.connect(object_viewed_receiver)Agora entre na página de produtos, clique na view de algum produto e no console do servidor, vejo os prints da object_viewed_receiver().
Explicação das alterações feitas acima
from .signals import object_viewed_signal: Importa um sinal personalizado chamadoobject_viewed_signalde um arquivosignals.pyno mesmo diretório. Esse sinal é usado para notificar partes do aplicativo quando um objeto é visualizado.def object_viewed_receiver(sender, instance, request, *args, **kwargs): Define uma função que atua como receptor para o sinalobject_viewed_signal. Essa função será chamada automaticamente quando o sinal for emitido. Ela recebe informações sobre o evento que disparou o sinal, incluindo o modelo que enviou o sinal (sender), a instância do modelo (instance), e o objeto de requisição HTTP (request).object_viewed_signal.connect(object_viewed_receiver): Conecta o receptorobject_viewed_receiverao sinalobject_viewed_signal. Isso significa que, sempre que o sinalobject_viewed_signalfor emitido em qualquer parte do aplicativo, a funçãoobject_viewed_receiverserá executada.
Esse código permite que você monitore quando um objeto específico é visualizado no seu aplicativo Django, executando a função object_viewed_receiver em resposta a esse evento.
Arquivo signals.py criado na aula passada
No arquivo signals.py, foi definido um sinal personalizado Django utilizando a classe Signal do módulo.
django_ecommerce/e_commerce/analytics/signals.py
from django.dispatch import Signal
object_viewed_signal = Signal(providing_args=['instance', 'request'])IMPORTANTE. A partir da versão 4.0 do Django, o signal não recebe mais o providing_args, portanto a forma correta do signals.py é essa abaixo.
Vejamos o que cada parte faz:
- Importação da Classe
Signal:from django.dispatch import Signal: Aqui, você está importando a classeSignaldo módulodjango.dispatch. No Django,Signalé uma forma de permitir que determinados remetentes notifiquem um conjunto de receptores quando ocorrem ações no sistema.
- Criação de um Sinal Personalizado (
object_viewed_signal):object_viewed_signal = Signal(providing_args=['instance', 'request']): Nesta linha, você está criando um sinal personalizado chamadoobject_viewed_signal.providing_args=['instance', 'request']: Esta parte é uma maneira de documentar quais argumentos são esperados pelos receptores deste sinal. Aqui, os argumentos sãoinstance(a instância do objeto que foi visualizado) erequest(o objeto de requisição HTTP).
IMPORTANTE. A partir da versão 4.0 do Django, o signal não recebe mais o providing_args, portanto a forma correta do signals.py é essa abaixo.
django_ecommerce/e_commerce/analytics/signals.py
from django.dispatch import Signal
object_viewed_signal = Signal()Melhorando o utils.py
A razão para usar request.META.get("REMOTE_ADDR", None) é garantir que, se o endereço IP não estiver disponível no request.META, como em situações onde o usuário está atrás de um proxy, a função retornará None em vez de causar um erro.
Isso torna o código mais seguro e previne falhas caso a chave "REMOTE_ADDR" não exista no dicionário.
django_ecommerce/e_commerce/analytics/utils.py
def get_client_ip(request):
# Obtém o valor do cabeçalho 'HTTP_X_FORWARDED_FOR' do objeto 'request.META'.
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
# Verifica se o cabeçalho 'HTTP_X_FORWARDED_FOR' está presente.
if x_forwarded_for:
# Se estiver presente, o cabeçalho pode conter uma lista de endereços IP separados por vírgulas.
# Portanto, dividimos a string em uma lista usando ',' como delimitador e pegamos o primeiro elemento da lista,
# que é o endereço IP do user.
ip = x_forwarded_for.split(",")[0]
else:
# Se o cabeçalho 'HTTP_X_FORWARDED_FOR' não estiver presente, usamos o endereço IP do user
# que está disponível em 'request.META["REMOTE_ADDR"]'.
ip = request.META.get("REMOTE_ADDR", None)
# Retornamos o endereço IP final.
return ip Continuando as alterações do models.py do analytics
django_ecommerce/e_commerce/analytics/models.py
from django.conf import settings
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from .signals import object_viewed_signal
from .utils import get_client_ip
User = settings.AUTH_USER_MODEL
class ObjectViewed(models.Model):
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE) # specific user, instance.id
ip_address = models.CharField(max_length=220, blank=True, null=True)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) # Product, Order, Cart, Address...
object_id = models.PositiveIntegerField() # User id, Product id, Order id
content_object = GenericForeignKey('content_type', 'object_id')
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.content_object} viewed on {self.timestamp}"
class Meta:
ordering = ['-timestamp'] # most recent saved show up first
verbose_name = 'Object viewed'
verbose_name_plural = 'Objects viewed'
def object_viewed_receiver(sender, instance, request, *args, **kwargs):
def object_viewed_receiver(sender, instance, request, *args, **kwargs):
c_type = ContentType.objects.get_for_model(sender) # instance.__class__
new_view_obj = ObjectViewed.objects.create(
user = request.user,
content_type=c_type,
object_id=instance.id,
ip_address = get_client_ip(request)
)
object_viewed_signal.connect(object_viewed_receiver)Agora entre na página de produtos e visualize alguns deles, depois entre na página de admin, acesse a parte de analytics/objectviewed.
E veja que agora temos uma forma de salvar e armazenar items visualizados.
Explicação das alterações
- Importação de
get_client_ip:from .utils import get_client_ip: Esta linha importa a funçãoget_client_ipdo móduloutilsque está no mesmo diretório que o arquivo atual, indicado pelo.. A funçãoget_client_ipé usada para obter o endereço IP do cliente que está fazendo a requisição.
- Função
object_viewed_receiver:- Esta função é um receptor (receiver) de sinal que é chamado quando um objeto é visualizado. Em Django, os sinais permitem que determinadas ações sejam executadas em resposta a eventos específicos.
- Parâmetros da Função:
sender: O modelo que enviou o sinal.instance: A instância do modelo que foi visualizada.request: O objeto de requisição HTTP.*args,**kwargs: Argumentos e palavras-chave adicionais.
- Corpo da Função:
c_type = ContentType.objects.get_for_model(sender): Obtém oContentTypepara o modelo que enviou o sinal.ContentTypeé um modelo do Django que armazena informações sobre os modelos usados em um aplicativo.new_view_obj = ObjectViewed.objects.create(...): Cria um novo registro no modeloObjectViewed, salvando quem viu o objeto, qual foi o objeto, o ID do objeto e o endereço IP do usuário que o viu.
- Criação do Registro
ObjectViewed:user = request.user: O usuário que fez a requisição.content_type = c_type: O tipo de conteúdo do objeto visualizado.object_id = instance.id: O ID da instância visualizada.ip_address = get_client_ip(request): O endereço IP do usuário, obtido pela funçãoget_client_ip.
- Conexão com o Sinal:
object_viewed_signal.connect(object_viewed_receiver): Conecta o receptorobject_viewed_receiverao sinalobject_viewed_signal. Isso significa que, sempre que o sinalobject_viewed_signalfor disparado, a funçãoobject_viewed_receiverserá chamada.


