477 lines
11 KiB
Markdown
477 lines
11 KiB
Markdown
|
||
**Ir a:**
|
||
[*Repositorio*](https://gitea.kickto.net/jp.av.dev/intro_Django#user-content-django-wiki),
|
||
[*Wiki*](https://gitea.kickto.net/jp.av.dev/intro_Django/wiki/_pages)
|
||
|
||
-------
|
||
|
||
### Creacion Entorno Virtual
|
||
```
|
||
python3 -m venv .django-env
|
||
```
|
||
|
||
### Usar virt-env
|
||
```
|
||
source .django-evn/bin/activate
|
||
```
|
||
|
||
### Installar Django
|
||
```
|
||
pip3 install Django
|
||
```
|
||
|
||
### Crear Proyecto
|
||
```
|
||
django-admin startproject NombreProyecto
|
||
```
|
||
|
||
### Detalle del proyecto:
|
||
|
||
- **init.py :** Tratar directorio como paquete de Python
|
||
- **settings.py :** Configuracion del Proyecto (*ej.TIMEZONE*)
|
||
- **urls.py :** "Indice" de urls del sitio
|
||
- **wsgi.py :** Interfaz entre apps del servidor y Django y/o Python frameworks
|
||
|
||
|
||
### Creación de base de datos
|
||
```
|
||
python3 manage.py migrate
|
||
```
|
||
|
||
### Correr servidor de pruebas
|
||
```
|
||
python3 manage.py runserver <ip:puerto>
|
||
```
|
||
--------
|
||
|
||
### Clases utilizadas por Django para manejar *'http Request and Responses'*
|
||
##### *módulo* ***django.http***
|
||
|
||
**HttpRequest:** Pasa como primer argumento a la función *view* una instancia de dicha clase (metadata del request).
|
||
|
||
**HttpResponse:** Cada *view* es responsable de enviar un objeto HttpResponse.
|
||
|
||
[Django Doc](https://docs.djangoproject.com/en/3.0/ref/request-response/#django.http.HttpRequest)
|
||
|
||
--------
|
||
|
||
## Primera Vista
|
||
|
||
crear Proyecto1/views.py
|
||
```
|
||
from django.http import HttpResponse
|
||
|
||
def primeravista(request):
|
||
return HttpResponse("Esta es la primera vista ٩(◕‿◕。)۶ con Django")
|
||
|
||
def otra(request);
|
||
return HttpResponse("Otra vista ( ̄▽ ̄)ノ con Django")
|
||
```
|
||
|
||
### 'Enlazar' vista con una URL
|
||
***urls.py***
|
||
```
|
||
from Proyecto1.views import primeravista, otra
|
||
|
||
url_patterns = [
|
||
path('admin/', admin.site.urls),
|
||
path('primera/', primeravista),
|
||
path('mas/', otra),
|
||
]
|
||
```
|
||
-------
|
||
|
||
## Paso de parametros en URL
|
||
|
||
*views.py*
|
||
```
|
||
def calcEdad(request, edad, ano):
|
||
periodo = ano - 2020
|
||
edadfutura = edad + periodo
|
||
doc = "<html><body><h3>En el %s tendras %s años</h3></body></html>" %(ano, edadfutura)
|
||
return HttpResponse(doc)
|
||
|
||
```
|
||
|
||
*urls.py*
|
||
```
|
||
from Proyecto1.views import primeravista, otra, verFecha, calcEdad
|
||
|
||
urlpatterns = [
|
||
...
|
||
path('edades/<int:ano>', calcEdad),
|
||
...
|
||
```
|
||
|
||
### Contenido Dinámico
|
||
*views.py*
|
||
```
|
||
import datetime
|
||
|
||
def verFecha(request):
|
||
fecha_ahora = datetime.datetime.now()
|
||
documento = "<html><body><h3> Hora y Fecha actual: %s</h3></body></html>" % fecha_ahora
|
||
return HttpResponse(documento)
|
||
```
|
||
|
||
*urls.py*
|
||
```
|
||
from Proyecto1.views import primeravista, otra, verFecha
|
||
|
||
urlpatterns = [
|
||
...
|
||
path('fecha/', verFecha),
|
||
...
|
||
```
|
||
|
||
--------
|
||
|
||
## Templates o Plantillas
|
||
*en su mayoria HTML*, se usan para separar la lógica de lo visual de un documento web.
|
||
"temas":["Vistas", "Modelos", "Plantillas", "Formularios", "Despliege"]
|
||
#Uso:
|
||
- Creación de objeto Template `plant = Template(doc_externo.read())`
|
||
- Creacion de contexto (**datos adicionales ej, vars, func., etc**) `ctx = Context()`
|
||
- Renderizado del objeto Template `documento = plant.render(ctx)`
|
||
|
||
*Proyecto1/plantillas/miplantilla.html*
|
||
```
|
||
<html><body><h3>Primera plantilla en Django ╮(︶▽︶)╭</h3></body></html>
|
||
```
|
||
|
||
*views.py*
|
||
```
|
||
from django.template import Template, Context
|
||
|
||
def primeravista(request):
|
||
doc_externo = open("/home/sat/weblocal/PildorasInf/Proyecto1/Proyecto1/plantillas/miplantilla.html", 'r')
|
||
plantilla = Template(doc_externo.read())
|
||
doc_externo.close()
|
||
ctx = Context()
|
||
documento = plantilla.render(ctx)
|
||
return HttpResponse(documento)
|
||
|
||
```
|
||
|
||
### Uso de variables en plantillas
|
||
|
||
*views.py*
|
||
```
|
||
from django.template import Template, Context
|
||
|
||
def primeravista(request):
|
||
nombre = "Zerafín"
|
||
apellido = "Menendes"
|
||
fecha = datetime.datetime.now()
|
||
doc_externo = open("/home/sat/weblocal/PildorasInf/Proyecto1/Proyecto1/plantillas/miplantilla.html", 'r')
|
||
plantilla = Template(doc_externo.read())
|
||
doc_externo.close()
|
||
ctx = Context({"nombre_persona":nombre, "apell_persona":apellido, "fecha":fecha})
|
||
documento = plantilla.render(ctx)
|
||
return HttpResponse(documento)
|
||
|
||
```
|
||
|
||
*miplantilla.html*
|
||
```
|
||
<html>
|
||
<body>
|
||
<h2 style="color: magenta">
|
||
Primera plantilla en Django ╮(︶▽︶)╭
|
||
</h2>
|
||
<p>El Nombre de prueba es: <strong>{{nombre_persona}}</strong></p>
|
||
<p>El Apellido de prueba es: <strong>{{apell_persona}}</strong></p>
|
||
<p>Día : {{fecha.day}}/{{fecha.month}}/{{fecha.year}}/</p>
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
### Acceso a objetos y propiedades desde plantillas (uso de dicc. en contexto)
|
||
|
||
*views.py*
|
||
```
|
||
class Persona(object):
|
||
def __init__(self, nombre, apellido):
|
||
self.nombre = nombre
|
||
self.apell = apellido
|
||
|
||
def primeravista(request):
|
||
p1 = Persona("Zerafín", "Menendes")
|
||
fecha = datetime.datetime.now()
|
||
doc_externo = open("/home/sat/weblocal/PildorasInf/Proyecto1/Proyecto1/plantillas/miplantilla.html", 'r')
|
||
plantilla = Template(doc_externo.read())
|
||
doc_externo.close()
|
||
ctx = Context({"nombre_persona":p1.nombre, "apell_persona":p1.apellido, "fecha":fecha})
|
||
documento = plantilla.render(ctx)
|
||
return HttpResponse(documento)
|
||
|
||
```
|
||
|
||
### Uso de listas en contexto y plantillas
|
||
|
||
*views.py*
|
||
```
|
||
temas_curso = ["Vistas", "Modelos", "Plantillas", "Formularios", "Despliege"]
|
||
|
||
ctx = Context({"nombre_persona":p1.nombre, "apell_persona":p1.apellido, "fecha":fecha, "temas":temas_curso})
|
||
```
|
||
|
||
### Estructuras de control de flujo en plantillas
|
||
|
||
*miplantilla.html*
|
||
```
|
||
<p><strong>Temas de estudio</strong></p>
|
||
<p>
|
||
<ul>
|
||
{% if temas %}
|
||
{% for tema in temas %}
|
||
<li>{{tema}}</li>
|
||
{% endfor %}
|
||
{% else %}
|
||
<p>Nada que mostrar</p>
|
||
{% endif %}
|
||
</ul>
|
||
</p>
|
||
```
|
||
*recordar: La lógica va en las vistas. Estas lineas son con el fin de comprender el funcionamiento de Django*
|
||
|
||
#### Jerarquía de llamadas desde plantilla
|
||
|
||
- Diccionario
|
||
- Atributo
|
||
- Método
|
||
- Índice lista
|
||
|
||
|
||
#### Métodos en plantillas
|
||
|
||
*miplantilla.html*
|
||
```
|
||
<p>El Nombre de prueba es: <strong>{{nombre_persona.upper}}</strong></p>
|
||
<p>El Apellido de prueba es: <strong>{{apell_persona.upper}}</strong></p>
|
||
```
|
||
|
||
### Tags
|
||
|
||
```
|
||
# autoescape on por defecto
|
||
{% autoescape on %}
|
||
{{ body }}
|
||
{% endautoescape %}
|
||
|
||
# Comentarios
|
||
{# COMENTARIO DE UNA LINEA #}
|
||
{% comment "nota opcional" %}
|
||
Comentario con nota, multilinea,
|
||
no visible para web inspector de navegador*
|
||
{% endcomment %}
|
||
|
||
# Herencia, para 'esqueletos' de plantillas (elementos comunes del sitio
|
||
{% block barra_lateral %}
|
||
<ul>
|
||
<li><a href="/">https://docs.djangoproject.com/en/3.0/ref/templates/language/</a></li>
|
||
<li><a href="https://docs.djangoproject.com/en/3.0/ref/templates/language/#template-inheritance">Blog</a></li>
|
||
</ul>
|
||
{% endblock %}
|
||
|
||
# Proteccion contra CSRF* (on por defecto)
|
||
|
||
<form method="post">{% csrf_token %}
|
||
|
||
# Cross Site Request Forgery
|
||
```
|
||
```
|
||
# for
|
||
{% for x, y in points %}
|
||
There is a point at {{ x }},{{ y }}
|
||
{% empty %}
|
||
No values
|
||
{% endfor %}
|
||
```
|
||
#### Variantes del ciclo for
|
||
|
||
- forloop.counter :`Itera con indexado 1`
|
||
- forloop.counter0 :`Itera con indexado 0`
|
||
- forloop.revcounter :`Iteracíon inversa con indexado 1`
|
||
- forloop.revcounter0 :`Iteracíon inversa con indexado 0`
|
||
- forloop.first :`Verdadero si es la primera iteración`
|
||
- forloop.last :`Verdadero si es la última iteración`
|
||
- forloop.parentloop :`Para 'loops' anidados, Este es el loop padre`
|
||
|
||
### Fitros
|
||
|
||
*miplantilla.html*
|
||
```
|
||
# filtro upper
|
||
<p>El Apellido de prueba es: <strong>{{apell_persona|upper}}</strong></p>
|
||
|
||
{% filter force_escape|lower %}
|
||
This text will be HTML-escaped, and will appear in all lowercase.
|
||
{% endfilter %}
|
||
|
||
{% firstof var1 var2 var3 %}
|
||
% firstof var1 var2 var3 "valor por defecto" %}
|
||
|
||
{% for tema in temas %}
|
||
<li>{{tema|first|lower}}</li>
|
||
{% endfor %}
|
||
|
||
```
|
||
|
||
[django-doc](https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#filter)
|
||
|
||
### Cargadores de Plantillas (loader)
|
||
|
||
De esta forma, el objeto *render* no adminte un contexto como parametro.
|
||
Debe recibir un *diccionario*
|
||
*views.py*
|
||
```
|
||
....
|
||
from django.template.loader import get_template
|
||
|
||
....
|
||
plantilla = get_template('miplantilla.html')
|
||
documento = plantilla.render({"nombre_persona":p1.nombre, "apell_persona":p1.apell, "fecha":fecha, "temas":temas_curso})
|
||
return HttpResponse(documento)
|
||
```
|
||
|
||
Especificar ruta a plantillas
|
||
*settings.py*
|
||
```
|
||
TEMLPATES = [
|
||
...
|
||
'DIRS': ['/home/sat/weblocal/PildorasInf/Proyecto1/Proyecto1/plantillas'],
|
||
...
|
||
]
|
||
```
|
||
|
||
### Simplificación de código con paquete shortcuts
|
||
[Django-doc](https://docs.djangoproject.com/en/3.0/topics/http/shortcuts/)
|
||
*views.py*
|
||
```
|
||
...
|
||
from django.shortcuts import render
|
||
|
||
# render recibe como argumento (request, 'plantilla', {contexto})
|
||
...
|
||
return render(request, "miplantilla.html", {"nombre_persona":p1.nombre, "apell_persona":p1.apellido, "fecha":fecha, "temas":temas_curso})
|
||
|
||
```
|
||
|
||
|
||
### Pantillas dentro de plantillas ( incrustadas )
|
||
|
||
ej. barra navegacion simple */plantillas/superior/barra.html*
|
||
```
|
||
<html>
|
||
<style>
|
||
#barra{
|
||
margin: 0;
|
||
padding: 0;
|
||
list-style: none;
|
||
text-transform: uppercase;
|
||
}
|
||
|
||
#barra li{
|
||
display: inline;
|
||
margin: 0 20px
|
||
}
|
||
</style>
|
||
<body>
|
||
<ul id="barra">
|
||
<li>Home</li>
|
||
<li>Servicios</li>
|
||
<li>Catálogo</li>
|
||
<li>Contacto</li>
|
||
<li>sobre Nosotros</li>
|
||
</ul>
|
||
</body>
|
||
</html>
|
||
```
|
||
Incrustar en *miplantilla.html*
|
||
```
|
||
<html>
|
||
<body>
|
||
{% include "superior/barra.html" %}
|
||
...
|
||
```
|
||
|
||
### Herencia de plantillas
|
||
Creación de plantilla padre,de la que se basa el resto de plantillas.
|
||
```
|
||
Parent.html
|
||
⭣
|
||
⮡ Child1.html {% extends "Parent.html" %}
|
||
⭣
|
||
⮡ Child2.html {% extends "Parent.html" %}
|
||
⭣
|
||
⮡ Child3.html {% extends "Parent.html" %}
|
||
```
|
||
|
||
ej. Parent
|
||
*plantillas/base.html*
|
||
```
|
||
<html>
|
||
|
||
<head>
|
||
|
||
<title>
|
||
{% block title %} {% endblock %}}
|
||
</title>
|
||
|
||
</head>
|
||
|
||
<body>
|
||
|
||
<h1>Titulo Común</h1>
|
||
<h3>Otro tit. vom.</h3>
|
||
|
||
{% block content %} {% endblock %}}
|
||
|
||
<p>Parrafo común</p>
|
||
|
||
</body>
|
||
|
||
</html>
|
||
|
||
```
|
||
|
||
ej. child
|
||
*childpage1.html*
|
||
```
|
||
{% extends "base.html" %}
|
||
|
||
{% block title %} Pagina hija {% endblock %}
|
||
|
||
|
||
{% block content %}
|
||
|
||
<p>Hoy es {{verFecha}}</p>
|
||
|
||
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/d1-UX6aR_TM?start=813" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||
|
||
{% endblock %}
|
||
```
|
||
Registrar vista *views.py* y url en *urls.py*
|
||
```
|
||
def herencia1(request):
|
||
fecha_ahora = datetime.datetime.now()
|
||
return render(request, "childpage1.html", {"verFecha":fecha_ahora})
|
||
|
||
# lo mismo para childpage2.html
|
||
```
|
||
```
|
||
from Proyecto1.views import primeravista, otra, verFecha, calcEdad, herencia1, herencia2
|
||
|
||
urlpatterns = [
|
||
...
|
||
path('hija1/', herencia1),
|
||
path('hija2/', herencia2),
|
||
]
|
||
```
|
||
|
||
-------
|
||
|
||
**Ir a:**
|
||
[*Repositorio*](https://gitea.kickto.net/jp.av.dev/intro_Django#user-content-django-wiki),
|
||
[*Wiki*](https://gitea.kickto.net/jp.av.dev/intro_Django/wiki/_pages) |