Tarea: Agregar mas a tu sitio web
Nuestro blog ha recorrido un gran camino hasta aqu í, pero aún hay espacio para la mejora. Lo siguiente, vamos a agregar nuevas características para borradores y su publicación. También vamos a agregar eliminación de post que ya no queremos mas.
Actualmente, nosotros creamos nuevos post usando nuestro formulario New Post y el post es publicado directamente. En lugar de publicar el post vamos a guardarlos com borradores. elimina esta linea en
blog/views.py
en los méetodos post_new
y post_edit
:post.published_date = timezone.now()
De esta manera los nuevos post serán guardados como borradores y se podrán revisar después en vez de ser publicados instantáneamente. Todo lo que necesitamos es una manera de listar los borradores. ¡Vamos a hacerlo!
¿Recuerdas el capítulo sobre los querysets? Creamos una vista
post_list
que muestra solamente los post publicados (aquellos que tienen un publication_date
no vacío).Es tiempo de hacer algo similiar, pero con borradores.
Vamos a añadir un enlace en
blog/templates/blog/base.html
en el encabezado. No queremos mostrar nuestro borradores a todo el mundo, entonces vamos a colocarlo dentro de la verificación {% if user.is_authenticated %}
, justo después del botón de agregar posts.<a href="<div data-gb-custom-block data-tag="url" data-0='post_draft_list'></div>
" class="top-menu"><span class="glyphicon glyphicon-edit"></span></a>
Siguiente: ¡urls! en
blog/urls.py
vamos a agregar:path('drafts/', views.post_draft_list, name='post_draft_list'),
Tiempo de crear una nueva vista en
blog/views.py
def post_draft_list(request):
posts = Post.objects.filter(published_date__isnull=True).order_by('created_date')
return render(request, 'blog/post_draft_list.html', {'posts': posts})
Esta línea
posts = Post.objects.filter(published_date__isnull=True).order_by('created_date')
se asegura de que solamente vamos a tomar post no publicados (published_date__isnull=True
) y los ordena por created_date
(order_by('created_date')
).Ok, el último pedazo es la plantilla. Crea un archivo
blog/templates/blog/post_draft_list.html
y agrega lo siguiente:
<div data-gb-custom-block data-tag="extends" data-0='blog/base.html'></div>
<div data-gb-custom-block data-tag="block">
<div data-gb-custom-block data-tag="for">
<div class="post">
<p class="date">created: {{ post.created_date|date:'d-m-Y' }}</p>
<h1><a href="
<div data-gb-custom-block data-tag="url" data-0='post_detail'></div>">{{ post.title }}</a></h1>
<p>{{ post.text|truncatechars:200 }}</p>
</div>
</div>
</div>
Se ve muy similar a nuestr
post_list.html
¿verdad?Ahora cuando vayas a
http://127.0.0.1:8000/drafts/
vas a ver la lista de post no publicados.¡Bien! ¡Nuestra primera tarea hecha!
Sería bueno tener un botón en el detalle del post que publique el post inmediatamente, ¿no?
Vamos a abrir
blog/templates/blog/post_detail.html
y cambiar estas líneas:
<div data-gb-custom-block data-tag="if">
<div class="date">
{{ post.published_date }}
</div>
</div>
por estas:
<div data-gb-custom-block data-tag="if">
<div class="date">
{{ post.published_date }}
</div>
<div data-gb-custom-block data-tag="else"></div>
<a class="btn btn-default" href="
<div data-gb-custom-block data-tag="url" data-0='post_publish'></div>
">Publish</a>
</div>
Como puedes ver, hemos agregado la línea
{% else %}
. Esto significa, que la condición de {% if post.published_date %}
no es cumplida (entonces no hay publication_date
), entonces queremos agregar la línea <a class="btn btn-default" href="{% url 'post_publish' pk=post.pk %}">Publish</a>
. Nota que estamos pasando la variable pk
en el {% url %}
.Tiempo de crear una URL (en
blog/urls.py
):path('post/<pk>/publish/', views.post_publish, name='post_publish'),
Y finalmente una vista (como siempre, en
blog/views.py
):def post_publish(request, pk):
post = get_object_or_404(Post, pk=pk)
post.publish()
return redirect('post_detail', pk=pk)
Recuerda, cuando creamos el modelo
Post
escribimos un método publish
. Se veía como esto:def publish(self):
self.published_date = timezone.now()
self.save()
¡Ahora finalmente podemos usarlo!
Y de nuevo al publicar el post, ¡somos redirigidos inmediatamente a la página
post_detail
!
Publish button
¡Felicitaciones! ¡Casi terminas, el último paso es un botón de eliminar!
Vamos a abrir
blog/templates/blog/post_detail.html
de nuevo y vamos a añadir esta línea<a class="btn btn-default" href="<div data-gb-custom-block data-tag="url" data-0='post_remove'></div>"><span class="glyphicon glyphicon-remove"></span></a>
Justo debajo de la línea co el botón editar.
Ahora necesitamos una URL (
blog/urls.py
):path('post/<pk>/remove/', views.post_remove, name='post_remove'),
Ahora, ¡Tiempo para la vista! Abre
blog/views.py
y agrega este código:def post_remove(request, pk):
post = get_object_or_404(Post, pk=pk)
post.delete()
return redirect('post_list')
La única cosa nueva es en realidad, eliminar el post. Cada modelo en django puede ser eliminado con
.delete()
. ¡Así de simple!Y en este momento, después de eliminar un post, queremos ir a la página web con la lista de posts, por eso usamos el
redirect
.¡Vamos a probarlo! ¡Vamos a la página con los post e intentemos eliminarlos!

Delete button
Si, ¡esto es lo último! ¡Acabas de completar este tutorial! ¡Eres asombroso!