Qual a formula para ocultar a PK que é utilizada como parametro na url do Django ?, verifiquei que colocando alguma PK manualmente na url tenho acesso a dados que não deveria ter acesso.
Qual a formula para ocultar a PK que é utilizada como parametro na url do Django ?, verifiquei que colocando alguma PK manualmente na url tenho acesso a dados que não deveria ter acesso.
Olá Gustavo, tudo bem com você?
Peço desculpas pela demora em obter um retorno.
Uma maneira de ocultar a primary key (PK) na URL é utilizando uma estratégia conhecida como "slug". O slug é um campo adicional na tabela que contém um valor único, legível por humanos e que representa o objeto de forma exclusiva.
No Django, você pode adicionar um campo SlugField
ao seu modelo e definir um método save()
que gere o valor do slug a partir de algum outro campo do modelo, como o título ou o nome. Em seguida, você pode usar o slug em vez da PK
na URL
:
from django.db import models
from django.utils.text import slugify
class Post(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('post/<slug:slug>/', views.post_detail, name='post_detail'),
]
# views.py
from django.shortcuts import get_object_or_404, render
from .models import Post
def post_detail(request, slug):
post = get_object_or_404(Post, slug=slug)
return render(request, 'blog/post_detail.html', {'post': post})
Isso permitirá que você acesse o post por meio de uma URL como post/meu-titulo-do-post/
em vez de post/1/
, ocultando assim a PK.
Todavia, caso o principal objetivo seja controlar o acesso aos dados do modelo, você pode definir uma permissão "view_post"
que permite aos usuários ver os posts e, em seguida, verificar se um usuário tem essa permissão antes de permitir o acesso a um objeto do modelo. Essa estratégia é padrão do próprio Django, pois ele possui um sistema de permissões embutido que permite controlar o acesso aos objetos do modelo. Na prática, teremos o seguinte:
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
permissions = [
("view_post", "Can view post"),
("add_post", "Can add post"),
("change_post", "Can change post"),
("delete_post", "Can delete post"),
]
# view.py
from django.shortcuts import get_object_or_404, render
from .models import Post
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
if not request.user.has_perm('blog.view_post', post):
# Usuário não tem permissão para visualizar este post.
# Aqui você pode redirecioná-lo para outra página ou retornar um erro 403 Forbidden.
return render(request, 'blog/access_denied.html')
return render(request, 'blog/post_detail.html', {'post': post})
A título de curiosidade, caso queira se aprofundar nos assuntos citados acima, recomendo as leituras abaixo:
O conteúdo recomendado acima está em inglês, o uso da língua inglesa é bem comum na área de tecnologia, mas não se preocupe, caso não tenha afinidade com essa linguagem, recomendo que utilize o tradutor do navegador para uma melhor compressão.
Espero ter ajudado. Continue mergulhando em conhecimento!
Abraços e bons estudos!