Django 1.7 apuntes (resumen)

Django es un framework de desarrollo web de código abierto, escrito en Python, que respeta el paradigma conocido como Model Template View. Fue desarrollado en origen para gestionar varias páginas orientadas a noticias de la World Company de Lawrence, Kansas, y fue liberada al público bajo una licencia BSD en julio de 2005; el framework fue nombrado en alusión al guitarrista de jazz gitano Django Reinhardt.

# -------------------------------------------------------------------
# - Python Django 1.7
# -------------------------------------------------------------------
  
  
# -------------------------------------------------------------------
# - Instalar herramientas
# -------------------------------------------------------------------
  
# Primero instalamos "python-setuptools"
sudo apt-get install python-setuptools
 
# Segundo instalamos Pip y despues de instalar comprobamos escribiendo la palabra "pip". y para comprobar app instalado pulsar: "pip freeze --local"
sudo easy_install pip
 
 
# -------------------------------------------------------------------
# - Entornos virtuales
# Existen 2 opciones: "VirtualEnv" y "VirtualenvWrapper"
 
# --
# VirtualEnv.- Es una herramienta que permite construir entornos de desarrollos aislados, y que puede ser muy util cuando se tiene diferentes proyectos y difeentes requisitos,.
sudo pip install virtualenv      # 1.- Instalación
virtualenv mi_proyecto           # 2.- Creacion de virtual
source mi_proyecto/bin/activate  # 3.- Activación
deactivate                       # Si se desa desactivar o slir de modo virtual
 
# --
# VirtualenvWrapper.- Extensión compilado para potenciar el "VirtualEnv", facilita notoriamente un gran numero de entornos virtuales
sudo pip install virtualenvwrapper   # 1.- Instalación
mkvirtualenv mi_proyecto             # 2.- Creacion de virtual
workon mi_proyecto                   # 3.- Activación
 
 
 
# -------------------------------------------------------------------
# PIP.- Es una herramienta para instalar y administrar paquetes de Python, y fue reemplazo de la herramienta "easy install".
# Los paquetes se deb instalar cuando se tiene el entorno virtual activado
pip install nombre_paquete             # Instalación de paquetes
pip uninstall nombre_paquete           # Desinstalación de paquetes
pip install nombre_paquete --upgrade   # Actualización de paquetes
pip freeze --local                     # Dependencias (para conoer las dependencias en nuestro entorno virtual) 
  
 
# -------------------------------------------------------------------
# Instalar Django (Cuando el virtualenv esta activado)
pip install django
 
 
# -------------------------------------------------------------------
# Crear proyecto (Cuando el virtualenv esta activado)
# 1.- Crear carpeta del proyecto
mkdir Mi_Proyecto
cd Mi_Proyecto
 
# 2.- Crear proyecto
django-admin.py startproject miproyecto
 
 
 
 
# -------------------------------------------------------------------
# Requeriments.- Un archivo requeriments contiene todas las dependencias de nuestro proyecto en Django, es muy im portante cuando queremos trabajar en equipo y cuando un tercero va a utilizar nuestra aplicacion, tambien es importante cuando quremos hacer un deployment de un proyecto para no estar instalandod ependecia por dependencia. Vamos a ver como tener las buenas practicas que debemos tener con este archivo. ya que tenemos que tener proyecto de 3 niveles.
# Paso 1: en el primer nivel crear una carpeta "requeriments" y dentro de ella crear todos los requeriments para cada entorno de desarrollo: "base.txt, local.txt, staging.txt, production.txt" y dentro de cada uno de ellos vamos a ubicar las dependencias necesarias solo para ese ambiente de desarrollo. De esta manera podemos instalar todas dependecias segun el ambiente de sarrollo que estamos trabajando. Para eso ejecutamos el siguiente comando:
pip install -r requeriments/local.txt   # Este archivo local hereda siempre del "base.txt"
 
 
# -------------------------------------------------------------------
# Crear apps
django-admin.py startapp nombre_aplicacion
 
 
# -------------------------------------------------------------------
# Migrar DB, (por primera ves) siempre que ponemos algun comando, debemos asignarle el archivo de configuracion
python manage.py migrate --settings=miproyecto.settings.local
 
 
# -------------------------------------------------------------------
# Ejecutar server, por defecto arranca en el puerto 8000
python manage.py runserver --settings=miproyecto.settings.local
 
# Si desea cambiar puerto, por ejemplo el puerto 8080
python manage.py runserver 8080 --settings=miproyecto.settings.local
 
 
# Si desea cambiar direccion de IP
python manage.py runserver 0.0.0.0:8080 --settings=miproyecto.settings.local
 
# -------------------------------------------------------------------
# Crear superuser
python manage.py createsuperuser --settings=miproyecto.settings.local
 
 
# -------------------------------------------------------------------
# Instalar Base de datos, para eso hay que instalar unas librerias
sudo apt-get install libpq-dev python-dev
sudo apt-get install postgresql postgresql-contrib
 
sudo service postgresql status     # 1.- Verificar si postgresql esta ejecutandose
sudo passwd postgres               # 2.- Cambiar la clave del usuario PostgreSQL
su - postgres                      # 3.- Iniciar session
createuser wilzonmb                # 4.- Crear usuario, y seguir el asistente
createdb mi_db                     # 5.- Crear nuestra base de datos
psql mi_db                         # Ir a la base de datos
ALTER ROLE wilzonmb WITH SUPERUSER; # Asignar permisos de super usuario a un usuario
\d                                 # Listar las tablas
 
 
# Vamos a cambiar la clave del usuario, para eso se tiene que ingresar a la base de datos la que va tener permiso, y le ponemos la clave '123456'
psql mi_db
ALTER USER wilzonmb WITH PASSWORD '123456';
 
\q      # 1.- Para salir de la consola
exit    # 2.- para salir del usuario
 
 
 
# -------------------------------------------------------------------
# Configuramos conexion DB en Django
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'miproyecto',
        'USER': 'wilzonmj',
        'PASSWORD': '123456',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}
 
# -------------------------------------------------------------------
# Instalar la dependencia que nos permitira conectar django con PostgreSQL, para saber las dependencias que tenemos, podemos ejecutar lo siguiente "pip freeze --local"
pip install psycopg2
 
 
# -------------------------------------------------------------------
# Crear nuestra primera migracion en PostgreSQL, nos ubicamos ne nuestro proyecto
python manage.py migrate --settings=miproyecto.settings.local
 
# Ejecutar server
python manage.py runserver --settings=miproyecto.settings.local
 
 
# -------------------------------------------------------------------
# Instalar 'pillow' para poder trabajar con imagenes en django nececitamos una libreria externa
pip install pillow
 
# Solucion si no se puede instalar Pillow
pip install --no-cache-dir -I pillow     # Si es que sale mensaje de que esta usando cache en la instalación y no te permite continuar con la instalación, con este comando se instalarán sin problemas
 
sudo apt-get install libjpeg-dev         # O instalar este software
 
 
# -------------------------------------------------------------------
# Instalar 'unipath' para rutas
pip install unipath
 
 
 
 
# -------------------------------------------------------------------
# 1.- Crear migraciones despues de crear modelos, con esto generamos el archivo de migracion, y luego con el comando "migrate" ejecutamos ese archivo de migracion generada.
python manage.py makemigrations Nombre_Aplicacion --settings=miproyecto.settings.local
 
# 2.- Con esto ejecutamos el archivo de migracion creado con el anterior comando (makemigrations)
python manage.py migrate Nombre_Aplicacion --settings=miproyecto.settings.local
 
 
 
# -------------------------------------------------------------------
# - Apuntes de migraciones
# Crear migracion falsa para hacer pruebas
python manage.py migrate --fake --settings=miproyecto.settings.local
 
# Listar las migraciones realizadas
python manage.py migrate --settings=miproyecto.settings.local -l
 
# Listar las migraciones realizadas según apps (según el nombre de aplicaion)
python manage.py migrate apps_nombre --settings=miproyecto.settings.local -l
 
# Deshacer la migracion, al listar las migraciones que tenemos en determinado nombre de aplicacion, solo tenemos que poner el correlativo del nombre del archivo para deshacer cambios. los nombre de archivos son algo asi.
# 0001_initial
# 0002_person_address
# 0003_initial
# 0004_remove_person_address
python manage.py migrate apps_nombre --settings=miproyecto.settings.local 0003
 
# Si ya no queremos esos cambios, una ves elinado cambios, podemos eliminar el archivo de migracion para que no ejecute mas.
rm apps_nombre/migrations/0004_remove_person_address.py
 
# -------------------------------------------------------------------
# Instalar tablib, para tratamiento, exportar datos a excel
pip install tablib
 
 
 
 
 
 
# -------------------------------------------------------------------
# -------------------------------------------------------------------
# Modelo.- El modelo es la representacion de nuestros datos, y esto contiene toda la informacion y el comportamiento de todos los datos que vamos almacenando, y generalmente u  modelo representa una tabla en una base de datos.
# ORM.- Django trabaja con un concepto "ORM" el cual abstrae la base de datos que estamos utilizando y la convierte en una base de datos orientado a objetos, donde todo lo veremos como clases y como objetos. Haciendo una comparacion con las base de datos relacionados, una clase vendria a ser una tabla en la base de datos y un objeto vendria a ser un registro en esa tabla.
# Definiendo models.py.- Un modelo es una clase en Python y ademas es un subclase de la clase "Model" que nos da Django, es por qeso que si vamos en ustro archivo "models.py" veremos importado el archivo models que nos Django, Cada atributo del modelo representa un campo en la tabla de la base de datos, y Django nos da una api para acceder a la bade de datos, para poder utilizar las Querys sin utilizar SQL y todo simplemente con Python. Ahora vamos a definir un modelo, los modelos se define en un archivo por convencion se llama "models.py" y que vienen por defecto en una creacion de una aplicacion, ejemplo:
# URL de campos (https://docs.djangoproject.com/en/1.7/ref/models/fields/)
from django.db import models
 
class Person(models.Model):    
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
 
 
 
# -------------------------------------------------------------------
# Campos
# Tipos de campos.- Hay muchos tipos de campos que Django nos da por defecto, aqui voy a listar campos más utilizados, cabe mencionar que cada tipo de campo ya vienen con las validacione que Django tambien te da por defcto.
 
# Para las cadenas de caracteres podemos utilizar:
# CharField()    # 
# TextField()    # Se utiliza para gran cantidad de texto
 
# Para número:
# IntegerField()         # 
# BigIntegerField()      # Soporta mayor cantidad de numero hasta 64 bits
# PositiveIntegerField() # Soporta solo numero positivos
# DecimalField()         # Soporta numeros decimales, podemos darle "max_digits=5" para darle un máximo numero de digitos y "decimal_places=2" para las posiciones decimales que queremos que tenga
 
# Si queremos 2 tipos de valores:
# BooleanField()    # Solo soporta true o false
 
# Fechas:
# DateField()        # Solo captura la fecha
# DateTimeField()    # Solo captura la fecha y el tiempo
# TimeField()        # Solo captura el tiempo
# Para las opciones de DateField(), DateTimeField() y TimeField() podemos darle las opciones de "auro_now" y "auto_now_add" que por defecto estan en False, pero nosotros podemos cambiarle a true, el "auto_now" se utiliza cada ves que un objeto es guardado o modifiado y es muy utlizado para las fechas de actualizacion, y el "auto_now_add" es utilizado cuando un objeto es guardado por primera ves y es muy usado para las fechas de creacion.
 
# Para archivos, imagenes:
# FileField()    # Para archivos
# ImageField()   # Para imágenes
# Ambas tienen atributo "upload_to" en que decimos en que lugar se va guardar los archivos que vayamos subiendo
 
# Para Correo:
# EmailField()   # Para correos electronicos, podefecto tienen másximo de 75 caracteres
 
# --
# Relacionar 2 modelos
# OneToOneField()    # Relaciona 2 modelos de 1 a 1
# ForeignKey()       # Relaciona 2 modelos de 1 a muchos
# ManyToManyField()  # Relaciona 2 modelos de muchos a muchos
 
# Ejemplo de: OneToOneField()    # Relaciona 2 modelos de 1 a 1
# Un usuario tiene un solo perfil
class User(models.Model):    
    username = models.CharField(max_length=50)
 
class Profile(models.Model):
    user = models.OneToOneField(User)
    edad = models.PositiveIntegerField()
         
 
# Ejemplo de: ForeignKey()       # Relaciona 2 modelos de 1 a muchos
# Una persona puede tener muchos carros, pero un carro pertenece solo a una persona
class Persona(models.Model):    
    username = models.CharField(max_length=50)
 
class Carros(object):
    user = models.ForeignKey(Persona)
    color = models.CharField(max_length=30)
         
# Ejempo de ManyToManyField()  # Relaciona 2 modelos de muchos a muchos
# Un alumno puede tener muchos cursos, y el curso puede tener muchos alumnos, en este caso crerá una tercera tabla y un campo extra, donde lo pondra claves primarias de las dos tablas
class Alumno(object):
    username = models.CharField(max_length=50)
 
class Cursor(object):
    user = models.ManyToManyField(Alumno)
    edad = models.PositiveIntegerField()
         
 
# -------------------------------------------------------------------
# Querysets.- Un Querysets es un conjunto de objetos que obtenemos despues de hacer la consulta a la base de datos, y para acceder a estos Django nos ofrece un API que podemos utilizar mediante Python.
 
#encoding=UTF-8
from django.db import models
  
class Author(models.Model):
    name = models.CharField(max_length=50)
    edad = models.IntegerField()
 
    def __unicode__(self):
        return '%s' % self.name
 
class Entry(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField(max_length=100)
    content = models.TextField()
     
    def __unicode__(self):
        return '%s' % self.title
         
# Vamos utilizar la ORM de Django para acceder a estos datos
# Para eso ingresamos al shell de Django
python manage.py shell
 
from principal.models import Author
 
# Método 1:
author = Author(name='Wilzon'. edad=98)    # Este modelo tiene 2 atributos
author                  # compruebo
author.save()           # Para guardar dentro del modelo y con esto ya tengo guardado un nuevo author en la base de datos
Author.objects.all()    # Para comprobar esto, hacemos la consulta en el modelo Author
 
# Método 2:
author.name = 'Pedro Picapiedra'
author.edad = 35
author.save()           # Para guardar dentro del modelo y con esto ya tengo guardado un nuevo author en la base de datos
Author.objects.all()    # Para comprobar esto, hacemos la consulta en el modelo Author 
 
# Método 3:
author.objects.create(name = 'Maria', edad = 30)    # con esto creamos un neuvo registro
Author.objects.all()    # Para comprobar esto, hacemos la consulta en el modelo Author 
 
 
# De la misma forma que ingresamos objetos al modelo Author, podemos hacerlo para el modelo entrada
author = author.objects.get(name = 'Wilzon')
author                  # compruebo este objeto que voy usar para importar en la creacion de la nueva entrada
 
# Ahora ya podemos crear un objeto del modelo entrada, pero para eso primeor debemos importar este modelo
from principal.models import Entry
 
Entry.objects.create(author = author, title = "Este es un titulo", content = 'Este es contenido')
Entry.objects.all()    # Compruebo listando los registros
 
 
# Practicamos consultas, operaciones despues de crear mucjhos registros en los 2 modelos 
from principal.models import Author, Entry
 
Entry.objects.all()                 # Retorna todos los registros del modelo
Entry.objects.all().count()         # Retorna la cantidad de los registros
Author.objects.filter(edad = 23)    # Retorna registros que tengan edad de 23 años
Author.objects.exclude(edad = 24)   # Retorna registros excluyendo el que tiene edad de 24 años
Entry.objects.filter(author__name = 'Wilzon')         # Retorna todas las entradas que escribio Wilzon
Author.objects.get(name = 'Wilzon')   # Retorna 1 solo registro, si obtiene mas de un elemento va a traer error, ya que unicamente se utiliza cuando estamos seguro de que hay un solo registro
Author.objects.all().order_by('edad')    # Ordenar por defecto de menor a mayor
Author.objects.all().order_by('-edad')   # Ordenar de mayor a menor
Author.objects.filter(name__contains = 'o')    # Listar autores que en el nombre cotenga la letra "o"
 
 
# -------------------------------------------------------------------
# Migraciones.- Las migraciones automatizan el proceso al momento de hacer los cambios.
# Cuando creamos un proyecto por primera ves y hacemos una migracion, Djando crea los modelos instalados en la variable "INSTALLED_APPS", vamos a crear nuestra primer aplicacion y le vamos a llamar "myapp" desde la consola
python manage.py startapp myapp    # Crear proyecto en Django
 
.
.
.
 
# Creamos un ejemplo:
from django.db import models
 
class Person(models.Model):    
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
 
# Para realizar la migracion en nuestrom proyecto vamos a nececitar de 2 comandos, "python manage.py makemigrations" que genera la migracion o mejor dichos no genra un archivo con los cambios que se realizar en una determinada aplicaion y los guarda en el directorio migrations y el comando "python manage migrate" que guarda los cambios de manera permanente en la base de datos y ejecuta las sentencias SQL neceasrias para que se guarde la migracion. Para empezar la migracion del modelo "Person" abrimos nuestro archivo "setting.py" y debemos agregar la palicacion en la variable "INSTALLED_APPS" 
INSTALLED_APPS = (
    .
    .
    .
    'myapp',  # Agregamos al final nuestra aplicaion
)
 
# Ahora desde la consola creamos migraciones, esto lo hacemos en 2 pasos
python manage.py makemigrations    # Crea archivos para migrarlo
python manage.py migrate           # Ejecuta esos archivos creados para migrarlo ;)
 
 
 
# Ver migraciones
python manage.py migrate -l          # Ver todas las migraciones, nos lista con los nombres de las migraciones, etc.
python manage.py migrate myapp -l    # Ver todas las migraciones por cada aplicacion, en este caso sobre la aplciaicon "myapp"
 
 
# Ejemplos:
# Ejemplo 01:
# Agregamos un campo "address" del model Person
    address = models.TextField(null = True, blank = True)
# Ahora desde la consola creamos migraciones, esto lo hacemos en 2 pasos ("python manage.py makemigrations" y "python manage.py migrate"), tal como lo hacemos en las lineas anteriores
  
 
# Ejemplo 02:
# Cambiar el nombre al campo "address" del model Person
    home_address = models.TextField(null = True, blank = True)
# Ahora desde la consola creamos migraciones, esto lo hacemos en 2 pasos ("python manage.py makemigrations" y "python manage.py migrate"), tal como lo hacemos en las lineas anteriores
  
# Ejemplo 03:
# Eliminar el nombre al campo "home_address" del model Person, no deberiamos elimianr directamenrte, es recomendable usar sistema de versiones comop el Git, para evr cambios realizados. En este caso solo lo he comentado para que no lo tome en cuanta
    #home_address = models.TextField(null = True, blank = True)
# Ahora desde la consola creamos migraciones, esto lo hacemos en 2 pasos ("python manage.py makemigrations" y "python manage.py migrate"), tal como lo hacemos en las lineas anteriores
 
# Ejemplo 04:
# Regresar en el historial de cambios, recuperar el nombre al campo "home_address" del model Person.
python manage.py migrate myapp  0003    # Con esto eligimos de una de las listas de migraciones que aparecen con su nomre (python manage.py migrate myapp -l)
 
# Resultado
    home_address = models.TextField(null = True, blank = True)
 
 
# Ejemplo 05:
# Agregamos un campo "birthday" del model Person
# Si intentamos agregar un campo llamado "birthday" y estmos en un entorno de produccion,
    birthday = models.DateField()
# Ahora desde la consola creamos migraciones, esto lo hacemos en 2 pasos ("python manage.py makemigrations" y "python manage.py migrate"), tal como lo hacemos en las lineas anteriores
# Si al hacer la migracion Dajngo nos pide que el campo no debe estar vacio, tenemos 2 opciones, editar y poner valores en null o ingrear por defecto en el mismo terminal, si eleigimos ingresar valor en el mismo terminal, escribimos lo siguiente.
 datetime.date.today()
 
 
 
# -------------------------------------------------------------------
# Vistas
# URL.- La URL tiene 2 parametros (Exprecion regular y la vista), pero podemos agregar un terer parametro el "name" para asignarle el nombre aun URL, y desde el template poder llamarlo de esta manera.
url(r'^articles/2015/$', views.special_case_2015),              # Dice que esta cadena no se debe escapar y debe estar tal cual, la "r" es opcional es comendado ponerlo. Al lado redecho tenemos la vista(views.special_case_2015) asociado a este URL adonde se envia la peticion. 
url(r'^articles/([0-9]{4})/$', views.year_archive),             # Nos dice que puede ser numeros de 0 al 9, y al costado el que esta en "{4} quiere decir que los numero pueden ser de 4 digitos.
url(r'^articles/([0-9]{4})/([0-9]+)/$', views.article_detail),  # Nos dice que puede ser numeros de 0 al 9, y al costado el que esta en "{4} quiere decir que los numero pueden ser de 4 digitos, y elq eu tiene "([0-9]+)" quiere ddecir que puede tener muchos digitos.
 
 
# Buenas pacticas de URL
# - Deberiamos crear un archivo "urls.py" por cada aplicacion que creamos, para tener todo separado y saber que url usan ciertos aplicaciones
url(r'^', include('apps.urls')),    # Este agregamos al archivo raiz de "urls.py", Con esto decimos que va utilizar el archico de mi aplicaion "app"
 
# Si bien el include solamente tiene un parametro, que es el archivos de urls que vamos a utilizar, a este se puede incluir unsegundo parametro, y seria el "namespace" que simpleente le da el nombre a este archivo de urls, para asi poder llamar a una url que se encuenra en esta aplicacion desde un template de esta manera "{% 'namespace:name' %}", esto basicamente se utiliza cuando tengamos 2 urls con el mismo nombre en apliciones diferentes y para que no se confundan al momento de ser llamadas desde los templates.
url(r'^', include('apps.urls', namespace="app")), 
 
{% 'namespace:name' %}    # Llamar a una url que se encuenra en esta aplicacion desde un template, esto basicamente se utiliza cuando tengamos 2 urls con el mismo nombre en apliciones diferentes y para que no se confundan al momento de ser llamadas desde los templates
 
 
# ---
# Vistas basadas en funciones.- Una vista es una funcion en Python, o una clase que recibe una peticiond e la web, que en este caso es enviado por una url, y que devuelve una respuesta. Por convension a este archivo se le llama "views.py"
 
# Una vista luce de esta manera
from django.http import httpResponse
 
def my_view(request):
    # Todo la logica para devolver
    # Una respuesta
    return httpResponse('Aqui la respuesta :)')
    # JsonResponse.- si es que la respuesta va a ser en Json
 
 
 
# Ahora lo enlazamos una URL a esta vista
from django.conf.url import patterns, url
 
urlpatterns = patterns('',
    url(r'^$', 'apps.principal.views.my_view'),    # Donde "principal" es la aplciaioan que hemos creado
)
 
# Si no quermos poner siempre "apps.principal.views.my_view" podemos cambiarlo asi:
 from django.conf.url import patterns, url
 
urlpatterns = patterns('apps.principal.views',
    url(r'^$', 'my_view'),
)
 
 
 
# ---
# Shortcuts.- son atajos que no da django no solo para poder enviar mejor una respuesta, sino que para realziar otro tipo de consultas, por omento nos concentraremos en e envio de respuestas.
 
# -
# - Render.- tiene que recibir 2 parametros obligatioriamente, primero la peticion (request) y el segundo el nombre del template que vamos a utlizar
#  Ejempplo:
from django.shortcuts import render
 
def my_view(request):
    # Todo la logica para devolver
    # Una respuesta
    return render(request, 'my_plantilla.html')
 
    # Tambien pdemos agregar unos parametros opciones, lo mas utilizados son un diccionario
    # return render(request, 'my_plantilla.html', {'name':'Wilzon'})
     
# -
# - Redirect.- Envia una redireccion a otra url, se puede usar de muchas formas
# Metodo 1: Podemos enviar un objeto al metodo redirect, Esto va a funcionar si dentro del modelo "MyModel" tenemos un metodo llamado "get_absolute_url()"
from django.shortcuts import redirect
 
def my_view(request):
    objeto = MyModel.objets.get(...)
    return redirect(objeto)
 
 
# Metodo 2: Podemos enviar tambien una vista como redireccion
from django.shortcuts import redirect
 
def my_view(request):    
    return redirect('mi-view-nombre')
 
 
# Metodo 3: Donde enviamos una URL como normalmente se hace
from django.shortcuts import redirect
 
def my_view(request):    
    return redirect('/algun/url/')
 
 
# Metodo 4: Donde tambien se puede enviar urls completas
from django.shortcuts import redirect
 
def my_view(request):    
    return redirect('http://WilznMB.com')
 
 
 
# ---
# Decoradores.- Es una funcion que recibe como parametro una funcion y devuelve otra funcion. Un decorador solo puede ser usada con vistas basados en funciones y en Django el decorador mas famoso es "login_required()"  que hace es verifiar si el usuario esta o no esta logeado y de acuerdo dar permisos para aceder a las vistas
# Ejemplo pasar una funcion como parametro
def saludo(nombre):
    return "Hola %s " % nombe
 
def llamar_saludo(func):
    nombre = "Wilzon"
    return func(nombre)
 
print llamar_saludo(saludo)
 
 
# Ejemplo 1: crear un decorador
def saludo(nombre):
    return "Hola %s " % nombe
 
def mi_decorador(func):
    def nueva_funcion(nombre):
        return func(nombre)
    return nueva_funcion
 
mi_saludo = mi_decorador(saludo)
print mi_saludo    # Con esto retorna una funcion que se llama: 
"<function .="" .models="" :="" __init__.py="" a="" absoluta="" absoluta.="" aca="" activada="" activo="" actual="" adelante="" agregar="" ahi="" ahora="" al="" algo="" algunos="" alter="" amneras="" aplaicaion="" aplciacion="" aplicacion="" aplicaciones="" aplicaion="" aplicaiones="" app1.views="" apps="" apt-get="" aqui="" archivo="" archivos="" archivvo="" arvhiso="" asi="" at="" auth="" ayuda="" base.txt="" base_dir="Path(__file__).ancestor(3)" blanco="" buenas="" cada="" cambiar="" capa="" caracteres="" carastres="" carpeta="" cerrar="" claro="" clase="" clases="" clave="" co="" codigo="" comando="" como="" complicaiones="" con="" condicion="" conectar="" conector="" configuracion="" configuraciones="" configuramos="" control:="" convension="" copiamos="" core="" correr="" corresponda="" cosas="" crea="" creamos="" crear="" createdb="" createuser="" creo="" cuando="" cursodjango="" d="" damos="" dar="" databases="{" datos="" db="" db.="" de="" debe="" debemos="" deben="" deberiamos="" decorador="" def="" definicion="" del="" dentro="" dependencias="" desarrollo:="" desde="" devuelve="" diferente="" directorios="" discusiones="" django="" django-admin.py="" djangoavanzado2="" donde="" dos="" ejecutamos="" ejecutar="" ejemplo="" ejemplo:="" el="" el:="" ella="" embargo="" en="" encontraban="" encontrado="" endif="" endtag="" entonrnos="" entorno="" entornos="" error="" ervicio="" es="" ese="" eso="" esos="" espacios="" esta="" estable="" estado.="" estamos="" estan="" estar="" estaran="" estas="" este="" estes="" esto="" estructuras="" etc.="" etiquetas:="" eves="" evitar="" evr="" excepcion="" existen="" explicita="" explicita.="" extends="" extra="" facilitan="" fila="" filtros:="" freeze="" from="" fuera="" funcion="" funcione="" funciones="" geneneran="" genera="" guarden="" hace="" hacemos="" hacer="" hae="" hambiente="" handler404="mysite.views.my_custom_page_not_found_view" hay="" hechas="" herencia:="" hola="" home="" identacion="" if="" iguales="" import="" importacion="" importaciones="" importamos="" importantes="" importar="" imports="" incluir="" informacion="" ingresar="" ingreses="" iniciar="" instalacion="" instaladas="" instalamos="" instalar="" instalara="" instalaran="" install="" instalo="" la="" las="" le="" libpq-dev="" limite="" linea="" lineas="" lista="" listar="" listo="" llevar="" lo="" local="" local.txt="" locales="" login="" los="" luego="" manage.py="" manejo="" manera="" mas="" mayor="" metodos="" mi="" mi_decorador="" migraciones="" misma="" mismo="" models="" modificaiones="" modulo="" momento="" motor="" multiples="" n="" necesitamos="" nestras="" nivel="" niveles="" no="" nombe="" nombre="" nos="" nuestro="" nueva_funcion="" nuevo="" nunca="" o="" objetivo="" obligatorios="" osea="" otro="" pagina="" paquete="" paquetes="" para="" parametro="" pasarle="" passwd="" password="" path="" pep="" perdida="" permisos="" permite="" pero="" persona="" peticion="" pide="" pip="" plantillas="" poner="" por="" postgres="" postgresql="" pre="" primero="" principal="" print="" privados="" problemas="" produccion="" programando="" programar="" proporcional="" proyecto="" proyectos="" pruebas="" psql="" psycopg2="" puede="" python="" python-dev="" python-social-auth="" q="" que="" recomendable="" recomendado="" recordar="" refiere="" reglas="" relativa="" relativa.="" requeriments="" requeriments.txt="" requeriments:="" retorna="" return="" runserver="" ruta="" rutas="" s="" saber="" salir="" se="" seguir="" segun="" segundo="" separadas="" separar="" ser="" service="" servidor="" session="" setting="" settings="" settings.py="" si="" siempre="" siguiente="" simple="" sin="" sincronizar="" siste="" social="" solo="" son="" south="" start="" startapp="" su="" subimos="" sudo="" suma="" syncdb="" tablas="" tag="" te="" tempalte="" template="" tenemos="" tener="" teniendo="" terceros="" testear="" tiene="" tipo="" tipos="" tips="" toda="" todas="" todo="" trabajando="" trabajo="" traen="" traer="" tu="" ubicarse="" ultimo="" un="" una="" unipath="" unipath.="" uno="" usa="" usar="" user="" usuario="" utilizar="" va="" vamos="" variable="" variables:="" verificar="" version="" views.-="" virtual="" virtualenv="" vistas="" voy="" with="" y="" ya="">
</function>