Taller básico de Django
¿Quienes somos?
DjangoQuilla es una comunidad de desarrolladores de django, emprendedores y estudiantes y entusiastas de Python y Django.
Nos reunimos 1 vez al mes en ÁreaDos.
Requisitos para el taller
- Python
- Virtualenv y virtualenwrapper
- Git
- Crear cuenta en GitHub
- Editor de texto (Sublime Text, Atom)
Contenido del taller
- Introducción a Python
- ¿Qué es Django?
- Instalando Django
- Primer proyecto
- Modelos
- Administrador
- Despliegue
- URLs
- Vistas
10. ORM de Django
11. Datos dinámicos en las plantillas
12. Plantillas
13. CSS
14. Extendiendo las plantillas
15. Extendiendo la app
16. Formularios
¿Qué es Django?
Imagen tomada de la presentación de David Whitton
¿Qué sucede cuando solicitan una página web?
Imágen tomada de devcode
Instalación de Django
mkdir tutorial-blog
cd tutorial-blog
# Para los que tienen instalado virtualenvwrapper
mkvirtualenv env-blog
workon env-blog
pip install django==1.9.7
Primer proyecto de Django
django-admin startproject blogproject
# En el archivo settings.py
TIME_ZONE = 'America/Colombia'
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Correr en consola
python manage.py migrate
python manage.py runserver
Modelos en Django
La programación orientada a objetos consiste que en lugar de escribir todo como una aburrida secuencia de instrucciones de programación podemos modelar cosas y definir cómo interactúan con las demás.
Entonces ¿Qué es un objeto? Es un conjunto de propiedades y acciones.
Imagen tomada de wikibooks
Objetos
Imagen tomada de csit
Gato
---------
color
edad
humor
dueño
ronronear()
rasguñar()
alimentarse(comida_de_gato)
ComidaDeGato
----------
sabor
Modelos en Django
python manage.py startapp blog
blogproject
├── blogproject
| __init__.py
| settings.py
| urls.py
| wsgi.py
├── manage.py
└── blog
├── migrations
| __init__.py
├── __init__.py
├── admin.py
├── models.py
├── tests.py
└── views.py
# Agrega la linea 'blog',
# En INSTALLED_APPS dentro del archivo settings.py
Creando el modelo Post
from django.db import models
from django.utils import timezone
class Post(models.Model):
author = models.ForeignKey('auth.User')
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
# Luego creamos las tablas para el modelo
# Vamos a consola y corremos
python manage.py makemigrations blog
python manage.py migrate blog
Administrador de Django
# Vamos a abrir el archivo blog/admin.py
# y reemplazar su contenido con esto:
from django.contrib import admin
from .models import Post
admin.site.register(Post)
# Luego corremos en consola
python manage.py runserver
# Vamos a esta direccion en el navegador
# http://127.0.0.1:8000/admin/
Si quieres saber más información del administrador ve a la documentación de Django
Expresiones Regulares
# Para no repetir URLs creamos patrones de ellas usando
# expresiones regulares
^ denota el principio del texto
$ denota el final del texto
\d representa un dígito
+ indica que el ítem anterior debería ser repetido por lo menos una vez
() para encerrar una parte del patrón
# Ejemplo
http://www.mysite.com/post/12345/
# Su expresión regular sería
^post/(\d+)/$
URLs de Django
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'', include('blog.urls')),
]
# Crea un nuevo archivo vacío en blog/urls.py
# y agrega estas 2 líneas
from django.conf.urls import include, url
from . import views
urlpatterns = [
url(r'^$', views.post_list),
]
Parte 2
Creando repositorio de GIT
# Abre la consola y ve a la carpeta del blogproject, luego escribe
git init
# Registra tu nombre y tu correo con los siguientes comandos
git config --global user.name "Tu Nombre"
git config --global user.email tu@correo.com
# Creamos un archivo llamado .gitignore con el sgte contenido
*.pyc
__pycache__
myvenv
db.sqlite3
/static
.DS_Store
# Luego
git status
git add --all .
git commit -m "Primer commit del taller con Django Barranquilla
# Vamos a github, creamos el repositorio y añadimos el remoto
git remote add origin https://github.com/<tu-usuario-github>/blogproject.git
git push -u origin master
Vistas de Django
# Abre el archivo blog/views.py
from django.shortcuts import render
def post_list(request):
return render(request, 'blog/post_list.html', {})
# Dentro de blog, crea una carpeta que se llame templates
# Dentro de templates, crea otra carpeta llamada blog
# Por ultimo crea un archivo llamado post_list.html
Aprende más de vistas con la documentación de django
¿Qué es HTML?
HyperText significa que es un tipo de texto que soporta hipervínculos entre páginas. Markup significa que hemos tomado un documento y lo hemos marcado con código para decirle a algo (en este caso, un navegador) cómo interpretar la página. El código HTML está construido con etiquetas, cada una comenzando con < y terminando con >. Estas etiquetas de marcado son elementos.
Etiquetas HTML útiles
<h1>Un título</h1> - para tu título más importante
<h2>Un subtítulo</h2> - para el título del siguiente nivel
<h3>Un subsubtítulo</h3> - ... y así hasta <h6>
<em>texto</em> - pone en cursiva tu texto
<strong>texto</strong> - pone en negrita tu texto
<br /> - un salto de línea (no puedes colocar nada dentro de br)
<a href="https://djangoquilla.com">link</a> - crea un vínculo
<ul><li>primer elemento</li><li>segundo elemento</li></ul> - crea una lista
<div></div> - define una sección de la página
Plantilla HTML
<!DOCTYPE html>
<html>
<head>
<title>Django blog</title>
</head>
<body>
<div>
<h1><a href="">Django Blog</a></h1>
</div>
<div>
<p>publicado el: 14.06.2014, 12:14</p>
<h2><a href="">Mi primer artículo</a></h2>
<p>Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis
vestibulum. Donec id elit non mi porta gravida at eget metus. Fusce dapibus,
tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa
justo sit amet risus.</p>
</div>
<div>
<p>publicado el: 14.06.2014, 12:14</p>
<h2><a href="">Mi segundo artículo</a></h2>
<p>Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis
vestibulum. Donec id elit non mi porta gravida at eget metus. Fusce dapibus,
tellus ac cursus commodo, tortor mauris condimentum nibh, ut f.</p>
</div>
</body>
</html>
Recuerda actualizar tu repo
# Recuerda hacer commit de los cambios importantes que hayas hecho
git status
git add --all .
git status
git commit -m "Cambie el HTML del sitio web"
git push
Curso sugerido de GIT básico
ORM de Django
python manage.py shell
# Todos los objetos
Post.objects.all()
from blog.models import Post
# Crear objetos
Post.objects.create(author=me, title='Sample title', text='Test')
from django.contrib.auth.models import User
User.objects.all()
me = User.objects.get(username='Bruce')
Post.objects.create(author=me, title='Sample title', text='Test')
Post.objects.all()
# Añade 2 ó 3 posts más y avanza a la siguiente parte.
# Filtrar objetos
Post.objects.filter(author=me)
Post.objects.filter(title__contains='title')
# Publicando un post
from django.utils import timezone
Post.objects.filter(published_date__lte=timezone.now())
post = Post.objects.get(id=1)
post.publish()
Datos dinámicos en plantillas
# Finalmente nuestro archivo blog/views.py debería verse así:
from django.shortcuts import render
from django.utils import timezone
from .models import Post
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'blog/post_list.html', {'posts': posts})
Si quieres leer un poco más acerca de QuerySets en Django, puedes darle un vistazo a la documentación
Plantillas de Django
# Variable
{{ posts }}
# Bucle for
{% for post in posts %}
{{ post }}
{% endfor %}
# Así debe quedar la plantilla post_list.html
<div>
<h1><a href="/">Django Blog</a></h1>
</div>
{% for post in posts %}
<div>
<p>publicado el: {{ post.published_date }}</p>
<h1><a href="">{{ post.title }}</a></h1>
<p>{{ post.text|linebreaks }}</p>
</div>
{% endfor %}
Actualiza tu repo
git status
git add --all .
git status
git commit -m "Modifiqué las plantillas para mostrar artículos de la base de datos"
git push
¿Qué es CSS?
CSS (Cascading Style Sheets, que significa 'hojas de estilo en cascada') es un lenguaje utilizado para describir el aspecto y el formato de un sitio web escrito en lenguaje de marcado (como HTML). Trátalo como maquillaje para nuestra página web
Instalación de Bootstrap
# Agrega estas lineas dentro del <head> de tu archivo .html
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
# Crea una carpeta static dentro de la aplicación blog
# Crea una carpeta llamada css dentro de static y dentro de ella
# un archivo que se llave blog.css
# En tu archivo blog/static/css/blog.css deberías añadir el siguiente código
h1 a {
color: #FCA205;
}
# Abre el archivo post_list.html y añade esta linea justo al principio
{% load staticfiles %}
# Luego, entre el <head> y </head>, después de los enlaces a los archivos CSS de Bootstrap
<link rel="stylesheet" href="{% static 'css/blog.css' %}">
Nueva tipografía y clases
# Añande a blog.css
body {
padding-left: 15px;
}
# Nueva tipografía al título. Añade en el head de post_list.html
<link href="http://fonts.googleapis.com/css?family=Lobster&subset=latin,latin-ext" rel="stylesheet" type="text/css">
# Ahora añadiremos la la familia de la fuente a nuestro CSS
h1 a {
color: #FCA205;
font-family: 'Lobster';
}
# Añadiremos una clase llamada page-header al div del encabezado
<div class="page-header">
<h1><a href="/">Django Girls Blog</a></h1>
</div>
# Añade la clase post al div que contiene una entrada del blog
<div class="post">
<p>published: {{ post.published_date }}</p>
<h1><a href="">{{ post.title }}</a></h1>
<p>{{ post.text|linebreaks }}</p>
</div>
Más clases CSS
.page-header {
background-color: #ff9400;
margin-top: 0;
padding: 20px 20px 20px 40px;
}
.page-header h1, .page-header h1 a, .page-header h1 a:visited, .page-header h1 a:active {
color: #ffffff;
font-size: 36pt;
text-decoration: none;
}
.content {
margin-left: 40px;
}
h1, h2, h3, h4 {
font-family: 'Lobster', cursive;
}
.date {
float: right;
color: #828282;
}
.save {
float: right;
}
.post-form textarea, .post-form input {
width: 100%;
}
.top-menu, .top-menu:hover, .top-menu:visited {
color: #ffffff;
float: right;
font-size: 26pt;
margin-right: 20px;
}
.post {
margin-bottom: 70px;
}
.post h1 a, .post h1 a:visited {
color: #000000;
}
Agregando un contenedor
# Agregamos unos div mas rodeando las etiquetas for, así:
<div class="content container">
<div class="row">
<div class="col-md-8">
{% for post in posts %}
<div class="post">
<div class="date">
{{ post.published_date }}
</div>
<h1><a href="">{{ post.title }}</a></h1>
<p>{{ post.text|linebreaks }}</p>
</div>
{% endfor %}
</div>
</div>
</div>
Recomendado el curso de HTMLy CSS de Codecademy
Extender plantillas
# Vamos a crear un archivo base.html en blog/templates/blog/
blog
└───templates
└───blog
base.html
post_list.html
# Luego ábrelo y copia todo lo que hay en post_list.html al archivo base.html
# Asegurate de pegar esta linea al inicio
{% load staticfiles %}
# Luego, en base.html reemplaza por completo tu <body> con esto:
<body>
<div class="page-header">
<h1><a href="/">Django Girls Blog</a></h1>
</div>
<div class="content container">
<div class="row">
<div class="col-md-8">
{% block content %}
{% endblock %}
</div>
</div>
</div>
</body>
Extender plantillas
# Abre tu archivo blog/templates/blog/post_list.html
# Elimina todo lo que no esté dentro del body
{% for post in posts %}
<div class="post">
<div class="date">
{{ post.published_date }}
</div>
<h1><a href="">{{ post.title }}</a></h1>
<p>{{ post.text|linebreaks }}</p>
</div>
{% endfor %}
# Agrega esta linea al inicio del archivo
{% extends 'blog/base.html' %}
# Coloca todo entre {% block content %} y {% endblock content %}
Creando enlaces y vista detalle
# Agregamos una etiqueta <a> alrededor del <h1>
<h1><a href="{% url 'blog.views.post_detail' pk=post.pk %}">{{ post.title }}</a></h1>
# Agregamos esta linea al archivo blog/urls.py
url(r'^post/(?P<pk>[0-9]+)/$', views.post_detail),
# Crea la vista en el archivo blog/views.py
from django.shortcuts import render, get_object_or_404
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})
# Crea la plantilla para post_detail.py
{% extends 'blog/base.html' %}
{% block content %}
<div class="post">
{% if post.published_date %}
<div class="date">
{{ post.published_date }}
</div>
{% endif %}
<h1>{{ post.title }}</h1>
<p>{{ post.text|linebreaks }}</p>
</div>
{% endblock %}
Actualiza tu repo
git status
git add --all .
git status
git commit -m "Agregué la vista y la plantilla para el detalle de un artículo, así como el CSS del sitio."
git push
Formularios en Django 1
# Creamos el archivo forms.py dentro de la carpeta de blog
# Pega las sgtes lines en el archivo forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'text',)
# Abre base.html para agregar un enlace en el div llamado page-header
<a href="{% url 'blog.views.post_new' %}" class="top-menu">
<span class="glyphicon glyphicon-plus">
</span>
</a>
# Luego creamos una la nueva URL en urls.py
url(r'^post/new/$', views.post_new, name='post_new'),
Formularios en Django 2
# Abre el archivo blog/views.py
from .forms import PostForm
def post_new(request):
form = PostForm()
return render(request, 'blog/post_edit.html', {'form': form})
# Creamos el archivo post_edit.html
{% extends 'blog/base.html' %}
{% block content %}
<h1>New post</h1>
<form method="POST" class="post-form">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
{% endblock %}
# Abre tu navegador y prueba que aparezca el formulario
Formularios en Django 3
# Guardando desde el formulario
from .forms import PostForm
from django.shortcuts import redirect
def post_new(request):
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.published_date = timezone.now()
post.save()
return redirect('blog.views.post_detail', pk=post.pk)
else:
form = PostForm()
return render(request, 'blog/post_edit.html', {'form': form})
# Comprueba que funcione. Debe crear un nuevo post y luego redireccionar
# a la pagina post_detail
Formularios en Django 4
# Editando desde el formulario
# Agrega esta url en tu archivo post_detail.html dentro del if post.published_date
<a class="btn btn-default" href="{% url 'post_edit' pk=post.pk %}">
<span class="glyphicon glyphicon-pencil">
</span>
</a>
# Agrega la url en blog/urls.py
url(r'^post/(?P<pk>[0-9]+)/edit/$', views.post_edit, name='post_edit'),
#Abramos el archivo blog/views.py y añadamos al final esto
def post_edit(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = PostForm(request.POST, instance=post)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.save()
return redirect('blog.views.post_detail', pk=post.pk)
else:
form = PostForm(instance=post)
return render(request, 'blog/post_edit.html', {'form': form})
Algo de seguridad
# Ahora mismo cualquiera puede crear un artículo. Hagamos que el botón de crear solo aparezca para ti
# Busca el enlace que crea nuevos post y coloca este bloque if alrededor de el
{% if user.is_authenticated %}
<a href="{% url 'post_new' %}" class="top-menu">
<span class="glyphicon glyphicon-plus">
</span>
</a>
{% endif %}
# Repite lo mismo para el enlace que permite editarlos
{% if user.is_authenticated %}
<a class="btn btn-default" href="{% url 'post_edit' pk=post.pk %}">
<span class="glyphicon glyphicon-pencil">
</span>
</a>
{% endif %}
Actualiza tu repo
git status
git add --all .
git status
git commit -m "Agregué vistas para crear/editar artículos del blog dentro del sitio web."
git push
¿Qué sigue?
- Tutorial de Django Girls (despliegue)
- Extensión del tutorial de Django Girls
- Tutorial oficial de Django
- New Coder tutorials
- Code like a Pythonista
- Crea un proyecto propio
- Crea un clon de una app famosa (instagram, twitter...)
- Colabora en proyectos Open Source
(ej: el Proyecto Tributo a Paul Walker)
Mantente en contacto
Taller de Django básico
By Javier D
Taller de Django básico
Presentación inicial para el taller de django
- 1,363