1
resposta

Como ocultar PK na url do Django

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.

1 resposta

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!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!