Adicione o campo slug dentro do modelo Django
O que é SlugField no Django?
É uma forma de gerar um URL válido, geralmente utilizando dados já obtidos. Por exemplo, usando o título de um artigo para gerar um URL.
Vamos supor que nosso blog tenha uma postagem com o título 'O livro Django de Geeksforgeeks' com a chave primária id = 2. Podemos nos referir a esta postagem com www.geeksforgeeks.org/posts/2
. Ou podemos fazer referência ao título como www.geeksforgeeks.org/posts/The Django book by Geeksforgeeks
.
Mas o problema é que os espaços não são válidos em URLs, eles precisam ser substituídos por % 20, o que é feio, tornando-o o seguinte, www.geeksforgeeks.org/posts/The%20Django%20book%20by%20geeksforgeeks
mas não está resolvendo URL significativo. Outra opção pode ser www.geeksforgeeks.org/posts/the-django-book-by-geeksforgeeks
.
Então, a lesma é agora the-django-book-by-geeksforgeeks
. Todas as letras são reduzidas e os espaços são substituídos por hifens -.
Suponha que nossos modelos de postagem no blog sejam semelhantes a este.
STATUS_CHOICES
=
(
(
'draft'
,
'Draft'
),
(
'published'
,
'Published'
),
)
class
Post(models.Model):
title
=
models.CharField(max_length
=
250
)
slug
=
models.SlugField(max_length
=
250
, null
=
True
, blank
=
True
)
text
=
models.TextField()
published_at
=
models.DateTimeField(auto_now_add
=
True
)
updated
=
models.DateTimeField(auto_now
=
True
)
status
=
models.CharField(max_length
=
10
, choices
=
STATUS_CHOICES,
default
=
'draft'
)
class
Meta:
ordering
=
(
'-published_at'
, )
def
__str__(
self
):
return
self
.title
Adicionando Slugify em nosso projeto:
Agora precisamos encontrar uma maneira de converter o título em slug automaticamente.
Nota: Adicione um novo arquivo util.py
no mesmo diretório onde o settings.py
arquivo foi salvo.
Queremos que este script seja acionado toda vez que uma nova instância do modelo Post for criada. Para isso, usaremos sinais.
import
string
from
django.utils.text
import
slugify
def
random_string_generator(size
=
10
, chars
=
string.ascii_lowercase
+
string.digits):
return
''.join(random.choice(chars)
for
_
in
range
(size))
def
unique_slug_generator(instance, new_slug
=
None
):
if
new_slug
is
not
None
:
slug
=
new_slug
else
:
slug
=
slugify(instance.title)
Klass
=
instance.__class__
qs_exists
=
Klass.objects.
filter
(slug
=
slug).exists()
if
qs_exists:
new_slug
=
"{slug}-{randstr}"
.
format
(
slug
=
slug, randstr
=
random_string_generator(size
=
4
))
return
unique_slug_generator(instance, new_slug
=
new_slug)
return
slug
Sinais no Django:
Em muitos casos, quando há uma modificação na instância de um modelo, precisamos executar alguma ação. Django nos fornece uma maneira elegante de lidar com essas situações. Os sinais são utilitários que permitem associar eventos a ações. Podemos desenvolver uma função que será executada quando um sinal a chamar.
No models.py
arquivo do aplicativo de postagens onde o Post Model foi definido, adicione-o no mesmo arquivo:
def
pre_save_receiver(sender, instance,
*
args,
*
*
kwargs):
if
not
instance.slug:
instance.slug
=
unique_slug_generator(instance)
pre_save.connect(pre_save_receiver, sender
=
Post)
A pre_save_receiver
função deve ser colocada separadamente fora do modelo Post.
Nota: Em urls.py
editar o caminho de detalhes com path('posts/', detail)
. Em views.py
editar a função de detalhe com
def
detail(request, slug):
q
=
Post.objects.
filter
(slug__iexact
=
slug)
if
q.exists():
q
=
q.first()
else
:
return
HttpResponse(
'<h1>Post Not Found</h1>'
)
context
=
{
'post'
: q
}
return
render(request,
'posts/details.html'
, context)
A última etapa é adicionar o link no arquivo HTML <a href=”/posts/{{ a.slug }}” class=”btn btn-primary”> Visualização </a>. Agora estamos prontos para ir para 127.0.0.1:8000/posts/title-you-have-added e ele irá mostrar a página details.html
.
As postagens do blog Acervo Lima te ajudaram? Nos ajude a manter o blog no ar!
Faça uma doação para manter o blog funcionando.
70% das doações são no valor de R$ 5,00...
Diógenes Lima da Silva