Aula 89 – Lidando com o Sinal do Objeto Visualizado
Aula 89 – Lidando com o Sinal do Objeto Visualizado
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
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_signal
de um arquivosignals.py
no 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_receiver
ao sinalobject_viewed_signal
. Isso significa que, sempre que o sinalobject_viewed_signal
for emitido em qualquer parte do aplicativo, a funçãoobject_viewed_receiver
será 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 classeSignal
do 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_ip
do móduloutils
que 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 oContentType
para 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_receiver
ao sinalobject_viewed_signal
. Isso significa que, sempre que o sinalobject_viewed_signal
for disparado, a funçãoobject_viewed_receiver
será chamada.