Recentemente gravei algumas aulas para auxiliar quem está começando a desenvolver para a Web utilizando Python e Django.
É um curso introdutório que não apresenta todo o processo de desenvolvimento, mas ensina como as coisas funcionam no Django para que você possa começar a aprender.
Documentação dos Sistemas de Autenticação do Django
Nesta etapa, vamos relacionar nossos modelos com a classe “User” do Django para podermos separar os objetos por usuário, de modo que um usuário tenha seus próprios registros no nosso sistema e que um usuário não acesse os registros de outros usuários.
Importe o User no models.py para poder criar chave estrangeira com ele
from django.contrib.auth.models import User
Crie um atributo na sua classe, neste caso criei no Animal
class Animal(models.Model): tipo = models.ForeignKey(Tipo, on_delete=models.PROTECT) ... telefone = models.CharField(max_length=17) usuario = models.ForeignKey(User, on_delete=models.PROTECT)
Execute o makemigrations para preparar seu banco de dados com as modificações
python manage.py makemigrations adocao
Esta mensagem indica que você está alterando uma tabela no banco que já tem registros. Como não falamos que ele pode ser “blank” e “null” você precisa fornecer um valor padrão. Por isso, vamos na opção “1” e depois digitar um valor qualquer para ser preenchido na nova coluna “usuario”, por exemplo ”0”.
Execute o migrate para atualizar o banco
python manage.py migrate
Inicie o servidor novamente e acesse a página para cadastrar um animal
python manage.py runserver
Tente cadastrar um animal e você terá o erro:
Isso aconteceu porque você também deve informar um usuário, mas no formulário não tem ele. Você pode atualizar suas views e colocar “usuario” nos “fields”, porém esse não é o jeito certo.
É aqui que entra um novo método que iremos sobrescrever nas views: o form_valid
Documentação do form_valid
O form_valid é o método chamado depois que submetemos um formulário, seja ele para inserir, alterar ou excluir. Ele vai verificar se os campos foram preenchidos, se se os valores estão de acordo e todas as outras verificações que se deve fazer. Por fim, ele cria um objeto e salva no banco de dados (quando chamamos o super).
Vá no “adocao/views.py” e procure o “AnimalCreate”. Ele já tem um método que sobrescrevemos, o “get_context_data”. Agora vamos sobrescrever o form_valid:
Agora vamos pegar o usuário que está “logado” e inserir ele como “usuario” nesse animal
Precisamos pegar o usuário antes de chamar o super(), se não ele vai dar aquele mesmo erro. Então, adicione form.instance.usuario = self.request.user antes dele:
def form_valid(self, form): # Define o usuário como usuário logado form.instance.usuario = self.request.user url = super().form_valid(form) return url
O “form.instance” vai manipular uma instância desse formulário com todos os dados recebidos antes de salvar no banco. Por isso, pegamos o “.usuario” porque é o nome do atributo criado na classe. O usuário logado sempre vai estar dentro do “request.user”. Aqui precisamos acessar ele pelo “self” porque estamos dentro de uma classe e queremos o usuário que fez essa requisição de salvar um animal.
A instrução retorna o endereço para onde redirecionar o usuário.
Fazer coisas depois de salvar o objeto no banco
É possível fazer coisas depois de salvar o objeto no banco. No exemplo anterior, adicionamos um usuário antes de chamar o super(). Basta fazer antes do return:
def form_valid(self, form): # Define o usuário como usuário logado form.instance.usuario = self.request.user url = super().form_valid(form) # código a fazer depois de salvar objeto no banco self.object.atributo = “algo” # Salva o objeto novamente self.object.save() return url
É possível acessar o objeto que foi criado pelo self.object. O método save() agora existe para salvar as alterações que você fez, por exemplo.
Como listar somente as Classes que são do “User”
Vamos alterar a view “AnimalList” dentro de “adocao/views.py” para listar somente os objetos que o próprio usuário que está logado cadastrou. No momento, nossa view é simples:
class AnimalList(LoginRequiredMixin, ListView): model = Animal template_name = "adocao/listas/list_animal.html"
As views que herdam a classe “ListView” tem um método que é chamado para listar todos os objetos daquela classe no banco. Nós podemos sobrescrever ele para colocar uma condição diferente do listar todos.
Método para alterar a listagem padrão de objetos
Crie o método “get_queryset” e altere o “object_list”:
def get_queryset(self): # O object_list armazena uma lista de objetos de um ListView self.object_list = Animal.objects.filter(usuario=self.request.user) return self.object_list
Pode ver alguma de suas listas como tem um for lá para o “object_list”.
Permitir que somente o usuário dono do objeto altere ou exclua o objeto
Uma maneira de garantir que o usuário não vai alterar o ID da sua URL para tentar ver outro registro é alterando o método padrão da sua classe que herdou um DeleteView ou UpdateView. Esse método é o “get_object”. É bem parecido com o da lista, porém ele recebe um ID pela URL para buscar exatamente um objeto e não uma lista deles.
Vamos fazer um procedimento que vai resultar uma tela de erro 404 se o usuário tentar burlar nosso site. No “adocao/views.py” faça a importação:
# Método que busca um objeto. Se não existir, da um erro 404 from django.shortcuts import get_object_or_404
Crie o método a seguir no “AnimalUpdate”:
# Altera a query para buscar o objeto do usuário logado def get_object(self, queryset=None): self.object = get_object_or_404(Animal, pk=self.kwargs['pk'], usuario=self.request.user) return self.object
O método “get_object_or_404” precisa de, pelo menos, dois parâmetros: a classe em que será feita a busca e os atributos que ela vai procurar. Neste caso procuramos pela chave primária (pk) e pelo usuário logado. Tente acessar o cadastro de algum animal com outro usuário e terá esse erro.
pk e usuario são atributos de Animal
self.kwargs[‘pk’] pega a chave primária da URL. Esse “pk” vem lá da URL:
path('editar/animal/<int:pk>/', …..)
Excluir somente objetos do usuário logado
O procedimento é exatamente o mesmo. Basta adicionar o método a seguir no seu “AnimalDelete”:
# Altera a query para buscar o objeto do usuário logado def get_object(self, queryset=None): self.object = get_object_or_404(Animal, pk=self.kwargs['pk'], usuario=self.request.user) return self.object
Fazer consultas personalizadas – Documentação
É possível fazer consultas personalizadas no banco de dados. Para mais detalhes, veja a documentação acima.
Algumas consultas interessantes
Listar todos os objetos:
Classe.objects.all()
Contar todos os objetos:
Classe.objects.all().count()
Buscar um objeto:
Classe.objects.get(pk=5)
Fazer uma consulta que retorna um ou mais objetos:
Documentação dos Sistemas de Autenticação do Django
Views de Autenticação (Login, Logout, Troca de senha, Reset de senha, etc)
Crie um novo app
Vamos separar do nosso módulo principal o gerenciamento de usuários para não ficar muita coisa em um módulo só. Para isso, crie um app chamado “usuarios”:
python manage.py startapp usuarios
Crie um arquivo de urls
Dentro do módulo novo, crie um arquivo “urls.py” com o seguinte código (o básico para criar e usar as urls):
from django.urls import path from django.contrib.auth import views as auth_views urlpatterns = [ # Aqui vão suas urls ]
Crie o diretório dos templates
Dentro do app “usuarios”, crie também uma pasta “templates” com uma pasta “usuarios” dentro dela.
Utilizando as Views existentes para Login
Existe uma View pronta já para funcionar como tela de login, basta criar uma url e apontar para ela, indicando qual o template será usado para fazer o login. É possível já usar um template que existe ou criar um novo só para login.
E agora crie o template login.html dentro do módulo “usuarios” com o seguinte conteúdo (que pode variar de acordo com o seu e no geral é igual algum form.html que você já tem):
{% extends 'adocao/base.html' %}
{% load static %}
{% load crispy_forms_tags %}
{% block header %} {% endblock %}
{% block container %}
<div class="container py-5">
<div class="row mt-5">
<div class="col-lg">
<h3>{{ titulo }}</h3>
</div>
</div>
<div class="row">
<div class="col-lg-5">
<form method="post">
<!-- Todo formulário tem que ter essa validação -->
{% csrf_token %}
<!-- Gera o formulário -->
{{ form|crispy }}
<button type="submit" class="btn btn-primary">
Entrar
</button>
</form>
</div>
</div>
</div>
{% endblock %}
Ative o módulo no settings.py
Agora é necessário ativar o novo módulo no settings.py para que ele funcione normalmente. Para isso, dentro de “INSTALLED_APPS” adicione (antes de fechar o vetor [ …. ]):
'usuarios.apps.UsuariosConfig',
Importe as URLSpara o projeto padrão
No arquivo “urls.py” que está junto com settings.py, importe o arquivo de urls que foi criado lá no módulo “usuarios”:
Por enquanto fizemos apenas a autenticação. Agora será necessário informar as páginas que só podem ser acessadas se o usuário fizer login.
Redirecionar o usuário depois do login
Por padrão, o usuário vai ser redirecionado para http://127.0.0.1:8000/accounts/profile/ depois de fazer login, mas não temos esse endereço. Podemos alterar a URL que o usuário será redirecionado após o login (LOGIN_REDIRECT_URL) e a URL que o usuário vai ver se tentar acessar alguma página que não tem login (LOGIN_URL). Configure também pra onde o usuário vai depois de fazer logout (LOGOUT_REDIRECT_URL). Adicione no settings.py essas duas constantes e o nome da URL:
# Nome da URL em que o usuário será redirecionado # https://docs.djangoproject.com/en/2.1/ref/settings/#auth LOGIN_REDIRECT_URL = 'index' LOGIN_URL = 'login' LOGOUT_REDIRECT_URL = 'login'
Definindo as páginas que precisam de login para serem acessadas
Lá nos seus arquivos “views.py”, independente do módulo, importe a classe que vai fazer as páginas requisitarem a autenticação para serem exibidas:
from django.contrib.auth.mixins import LoginRequiredMixin
Criando as heranças
Agora, nas suas classes/métodos dentro do views.py basta criar uma herença para LoginRequiredMixin e adicionar o atributo login_url = reverse_lazy(‘login’).
Exemplo:
class CidadeUpdateView(LoginRequiredMixin, UpdateView): login_url = reverse_lazy('login') ...
Atenção: O LoginRequiredMixin precisa ser importado antes de outras coisas e o método reverse_lazy tem que estar importado (from django.urls import reverse_lazy).
Criando uma tela para o usuário alterar sua senha
Também existe uma View que faz todo esse trabalho para nós (PasswordChangeView). Ela é semelhante à url de login e precisamos passar mais um parâmetro pra ela: “success_url”, que nada mais é do que para onde o usuário vai ser redirecionado após alterar a senha.
Para isso, vá no “urls.py” do módulo “usuarios” e importe o “reverse_lazy” no início do arquivo:
Pronto, basta acessar http://127.0.0.1:8000/alterar-minha-senha/ que você vai ver o formulário para alteração de senha. A View utiliza o mesmo formulário de Login, por isso usamos o “extra_context” para enviar o título da página.
Criar link para usuário
Agora basta criar mais um link no seu menu para facilitar a troca de senha:
Controle de acesso ao conteúdo diretamente nos templates
Nos templates também é importante verificar se o usuário fez o login para poder mostrar algumas coisas ou não. Isso é, basicamente, simples e envolve usar um if/else para verificar a autenticação.
Primeiro vamos no nosso menu para esconder alguns links. Vá no seu arquivo base do template (ex. base.html) e faça algo parecido com seu menu:
{% if request.user.is_authenticated %} <!-- Links/Conteúdo exibidos apenas para usuários logados --> {% endif %}
Mostrando dados do usuário
Lá nos templates é possível mostrar algumas informações do usuário por meio da instrução “request.user.atributo”. Exemplos:
Mostrar o primeiro nome: {{ request.user.first_name }}
Este framework permite fazer o controle de acesso à determinadas URL de acordo com o grupo em que os usuários pertencem.
Documentação do plugin/framework:
Controle de acesso por grupo
Instalar o plugin (aqui no IFPR já está instalado)
pip install django-braces
Para ver os grupos que você tem ou para criar mais, acesse:
Você pode adicionar um grupo pelo próprio Django Admin. Vamos criar dois grupos:
Administrador
Usuário
Quando criamos um usuário pelo comando (python manage.py createsuperuser), esse usuário passa a ter acesso total ao nosso projeto. É possível remover/adicionar o status de superusuário ao editar algum usuário pelo Django Admin.
Definindo que uma URL/View nossa precisa ter um usuário que pertence a um determinado grupo
Vá no seu arquivo “adocao/views.py” e importe o módulo para controle de acesso por grupo:
from braces.views import GroupRequiredMixin
Agora, basta fazer uma herança nas suas views para GroupRequiredMixin e criar o atributo group_required na sua classe. É importante notar que a primeira herança deve ser do GroupRequiredMixin. Por exemplo:
No nosso projeto, vamos fazer com que os cadastros de Cidade, Estado, Tipo e Raca sejam somente visualizados pelo administrador (inserir, alterar, excluir e listar).
class EstadoCreate(GroupRequiredMixin, LoginRequiredMixin, CreateView): group_required = u"Administrador" ...
Ajustar o template de login para redirecionar usuários autenticados
Só vamos mostrar o form se o usuário não estiver autenticado.
{% if request.user.is_authenticated %} <h4 class="mt-4 text-danger">Você não pode fazer isso!</h4> Redirecionando para a página inicial em 5 segundos... <meta http-equiv="Refresh" content="5; url={% url 'index' %}" /> {% else %} <form method="post"> <!-- Todo formulário tem que ter essa validação --> {% csrf_token %} <!-- Gera o formulário --> {{ form|crispy }} <button type="submit" class="btn {{ classe }}"> {{ botao }} </button> </form> {% endif %}
class Pessoa(models.Model): nome = models.CharField(max_length=50, verbose_name="Qual seu nome?", help_text="Digite seu nome completo") nascimento = models.DateField(verbose_name='data de nascimento') email = models.CharField(max_length=100) cidade = models.ForeignKey(Cidade, on_delete=models.PROTECT)
verbose_name – Nome (label) que vai aparecer no formulário para identificar o campo/atributo.
help_text – Texto extra de ajuda para ser mostrado com o “widget” do formulário. É útil para documentar mesmo que seu campo não seja usado em um formulário.
null – Se True, o Django pode usar valores nulos (null) no banco de dados. Padrão é False
blank – Se True, é permitido o campo estar em “branco” (vazio). O padrão é False.
default – O valor padrão para o campo.
unique – Se True, aquele atributo vai ser único no banco de dados. O padrão é False.
Para os campos de data, ainda deve-ser preencher dois atributos:
auto_now=True – Adiciona a data/hora toda vez que o objeto é salvo no banco. Geralmente, usado para verificar a última data/hora de modificação do objeto.
auto_now_add=True – Adiciona a data/hora toda vez que o objeto é criado no banco. Geralmente, usado para guardar a data que o objeto foi criado.
models.ForeignKey(Classe, on_delete=models.PROTECT) – chave estrangeira representada por um select no formulário. Precisa informar a classe do relacionamento e o modo de relação quando algum objeto da Classe for excluído (PROTECT, CASCADE, etc)
Ao executar makemigrations, você está dizendo Django que você fez algumas mudanças em seus modelos (neste caso, você fez novas modificações) e que você gostaria que as alterações sejam armazenadas como uma migração. Para isso, execute:
$ python manage.py makemigrations seu_modulo_app
Agora rode omigrate para criar essas tabelas dos modelos no seu banco de dados:
No arquivo views.py é necessário importar todos os modelos, assim como fizemos no admin:
from .models import *
Também já iremos importar um método para redirecionar o usuário depois de efetuar o cadastro:
from django.urls import reverse_lazy
Por fim, vamos importar as Views (classes) que utilizaremos como “Pai” para nossas telas de cadastro (inserir, alterar e excluir):
from django.views.generic.edit import CreateView, UpdateView, DeleteView
Agora podemos criar nossas classes conforme o exemplo abaixo:
class EstadoCreate(CreateView): model = Estado fields = ['sigla', 'nome'] template_name = 'formulario.html' success_url = reverse_lazy('index')
class CidadeCreate(CreateView): model = Cidade fields = ['nome', 'estado'] template_name = 'formulario.html' success_url = reverse_lazy('index')
Agora basta fazer esse mesmo esquema para todos as classes que você deseja criar um formulário de cadastro no seu projeto.
Criando um formulário padrão para usar em diversos modelos
Você pode criar um arquivo na pasta “templates” chamado “formulario.html”, por exemplo. Dentro dele ajuste o layout como preferir e crie um formulário conforme abaixo:
Existe um plugin (https://django-bootstrap4.readthedocs.io/en/latest/) que faz a geração do formulário e das mensagens de erro de validação conforme o Bootstrap 4. Para ativá-lo, vá no settings.py, procure por INSTALLED_APPS e adicione o módulo do plugin. Adicione, também, a constante no settings para definir o tipo padrão de templates logo depois do INSTALED_APPS.:
INSTALLED_APPS = [ ... 'crispy_forms', ]
CRISPY_TEMPLATE_PACK = 'bootstrap4'
No seu “formulario.html”, por exemplo, carregue o plugin depois de dar um load no static:
{% load crispy_forms_tags %}
No código HTML do formulário altere {{ form.as_p }} para {{ form|crispy }}
Agora atualize a página.
Criando uma tela para atualizar
O processo para atualizar registros é muito parecido com o CreateView. Portanto, altere apenas a classe que o método lá no views.py extende para UpdateView. O restante é a mesma coisa. Por exemplo:
class EstadoUpdate(UpdateView): model = Estado fields = ['sigla', 'nome'] template_name = 'formulario.html' success_url = reverse_lazy('index')
Para criar a URL é necessário passar o ID do registro que será alterado e qual o tipo dele. Por padrão, todas as tabelas no Django criam um campo “id” do tipo inteiro. Então, crie uma nova url no seu urls.py:
Usando o mesmo form, vai parecer que você está inserindo/salvando um registro. Então, crie um novo formulário personalizado com uma mensagem de exclusão:
<form method="post"> {% csrf_token %} <p>Tem certeza que deseja excluir o registro "{{ object }}"?</p> <input type="submit" class="btn btn-danger" value="Sim, excluir."> </form>
Listando objetos do banco de dados
Importe o método ListView:
from django.views.generic.list import ListView
Crie um método no views.py que extende ListView e informe qual o modelo será usado e o template:
class EstadoList(ListView): model = Estado template_name = 'adocao/listar_estados.html'
Agora a tela de listagem você tem que fazer uma para cada por causa dos nomes dos atributos de cada modelo. Exemplo:
<table class="table table-striped"> <tr> <th>ID</th> <th>Sigla</th> <th>Nome</th> <th>Opções</th> </tr> {% for estado in object_list %} <tr> <td>{{estado.pk}}</td> <td>{{estado.sigla}}</td> <td>{{estado.nome}}</td> <td> editar excluir </td> </tr> {% empty %} <tr> <td colspan="3">Nenhuma cidade cadastrada!</td> </tr> {% endfor %} </table>
Agora, para colocar os links para as páginas de “alterar” e “excluir”, modifique a tabela adicionando a URL no formato do Django, passando o “pk” como parâmetro:
Criando a primeira tela com classes (método mais utilizado desde a versão 2), conhecido como Class-based Views para realizar as tarefas do seu sistema, como inserir, cadastrar, exibir uma página, etc.
No arquivo Adocao/cadastros/views.py importe a classe genérica para exibir uma página simples e depois crie sua primeira classe para “renderizar” um template (HTML):
from django.views.generic import TemplateView
# Create your views here.
class IndexView(TemplateView):template_name = "index.html"
Como funcionam as classes dentro do “views”:
class NomeDaPaginaView(ClassePai): template_name = "sua_pagina.html"
Criando um template em HTML para ser usado pelas Views
Primeiro altere a configuração do arquivo Adocao/Adocao/settings.py lá na configuração dos templates:
Procure por: ‘DIRS’: [],
E troque por: ‘DIRS’: [ os.path.join(BASE_DIR, ‘templates’) ],
Agora crie uma pasta chamada ‘templates‘ dentro da pasta da sua aplicação ‘animais’. Dentro dela você pode criar as páginas HTML que vai usar como suas telas (templates). Por exemplo: animais/templates/index.html
Definindo as URLS do seu sistema
Por padrão, os endereços ficam registrados nos arquivos urls.py. Cada app pode ter seus próprios endereços e o seu Projeto (Adocao) também pode ter as suas.
Primeiro crie o arquivo “urls.py” dentro do seu app: animais/urls.py.
Faça a importação da biblioteca que gerencia as urls e das classes/métodos criados nos views.
from django.urls import path
from .views import IndexView
Crie uma url dentro do vetor de urls desse app. Os parâmetros são (nessa ordem): endereço, método/classe do views, nome da url no sistema.
Edite o arquivo Adocao/urls.py e inclua a biblioteca “include” depois de importar a biblioteca “path”.
from django.urls import path, include
Dentro da sua lista de urls, adicione um nome padrão para importar todas as suas urls do app:
urlpatterns = [ # Vai incluir todas as URLS do app animais neste padrão path('', include('animais.urls')), path('admin/', admin.site.urls), ]
Se deixar ‘’ (aspas vazias) não precisa digitar nada na URL pra aceitar este padrão.
Definindo o diretório STATIC para armazenar seu CSS, imagens, JS, etc.
Dentro do diretório Adocao, raiz do projeto e não junto com settings.py, crie uma pasta chamada “static” e coloque lá todo seu css, js, imagens, etc.
Somente os arquivos HTML ficam dentro da pasta template de cada app porque eles podem ser exclusivos daquele app. A ideia da pasta static é disponibilizar as imagens, js e css para todos os apps e não somente um.
No arquivo Adocao/settings.py acrescente uma configuração para o Django procurar a pasta static na raiz do seu projeto (você pode ter várias pastas statics no seu PC):
Sempre em vez de colocar o caminho real, deve ser utilizado o esquema do static acima para referenciar algo que tem lá.
Reaproveitando um template
No Django é possível reutilizar um arquivo html (template) reescrevendo apenas algumas partes dele. Para isso, crie blocos de código no seu arquivo de modelo. Por exemplo:
No seu arquivo que deve ser igual a este anterior, pasta “estender” ele como se fosse uma herança e depois só é necessário reescrever os blocos que você quer alterar. Exemplo:
Seguindo o passo a passo da instalação do Runescape no Linux, tive o seguinte problema:
......
Os pacotes a seguir têm dependências desencontradas:
runescape-launcher : Depende: libglew1.10 (>= 1.10.0-3) mas não é instalável
E: Impossível corrigir problemas, você manteve (hold) pacotes quebrados.
A solução foi remover a versão instalada do libglew1.X e instalar ele manualmente na versão 1.10. Para isso:
Remova o pacote que tem no seu PC: sudo apt-get remove libglew1.*
Baixe e instale (dando dois cliques no arquivo mesmo) a versão 1.10 de um dos repositórios a seguir: https://packages.ubuntu.com/trusty/amd64/libglew1.10/download
Instale novamente o launcher: sudo apt-get install -y runescape-launcher
Este tópico tem como objetivo guiar a instalação e criação de ambientes virtuais (virtualenv) no Windows.
Considerando que você já tem o Python instalado, bem como as variáveis de ambiente e o “pip”, siga o procedimento a seguir.
– Instalar pacote para criação de ambientes virtuais pip install virtualenv
– Instalar pacote para gerenciamento dos ambientes virtuais pip install virtualenvwrapper-win
– Crie um ambiente virtual mkvirtualenv nome_do_ambiente
– Ative o ambiente virtual recém criado workon nome_do_ambiente
Pronto. Agora é só instalar os pacotes que deseja ter nesse ambiente virtual que você acabou de criar e ativar. Você pode ter quantos ambientes desejar e eles, por padrão, ficam dentro no diretório Envs dentro da pasta do usuário. Por exemplo: C:\Users\rafael\Envs
O procedimento a seguir serve para instalação do Django e de mais três coisas úteis para ele: o bootstrap, o braces para controle de acesso e o crispy-forms para geração de formulários conforme os padrões do bootstrap. Não esqueça de ativar o ambiente virtual que você deseja instalar os pacotes: workon nome_do_ambiente.
– Instalação dos pacotes no ambiente virtual desejado.
pip install django
pip install django-bootstrap4
pip install django-braces
pip install django-crispy-forms
Meu computador com o Microsoft Windows 10 estava com 100% da utilização do disco sempre que ligava. Procurei vários tutoriais na Internet, mas o problema ainda insistia.
Já tentei várias coisas, como: aquele comando RestoreHealth, desativar paginação, limpar a inicialização de arquivos, excluir arquivos temporários, pontos de restauração e por aí vai. Porém, o problema do disco 100% ainda insistia.
Então notei um processo do Microsoft Office chamado Click To Run e resolvi desativá-lo. Pronto, problema do disco 100% resolvido!
Nas versões mais recentes do Microsoft Office, o processo antigo de desativar e deletar o “ClickToRunSvc” não funciona mais. Agora deve-se seguir o seguinte processo:
Vá no menu Iniciar e procure por “Serviços” (ou aperte o atalho Windows + R e digite services.msc)
Procure por “Serviço Clique para Executar do Microsoft Office” e dê dois cliques
Em “Tipo de inicialização” coloque “Manual“
Depois é só dar “Ok” e fechar as telas
Obrigado ao Vinícios e ao Gustavo que nos alertaram nos comentários.