Algo interesante que nos aporta django-command-extensions es poder crear una representación gráfica de nuestros modelos (o por decirlo de otro modo nuestro esquema de base de datos) con tan sólo un comando. Esto es posible gracias a GraphViz y el resultado es algo parecido a un diseño UML. Para poder utilizar este comando debemos tener instalado pygraphviz y por supuesto la aplicación django_extensions debe estar incluída en el setting INSTALLED_APPS de nuestro proyecto.
Para instalar pygraphviz en Linux nos bastará con utilizar el comando:
apt-get install python-pygraphviz
Una vez hemos instalado django-command-extensions y pygraphviz podremos crear un archivo dot, formato utilizado por GraphViz ó una imagen. En nuestro caso vamos a crear un archivo PNG que incluya los modelos de todas las aplicaciones de nuestro proyecto. Para ello usamos el comando:
./manage.py graph_models -a -g -o mis_modelos.png
Con el parámetro -o especificamos el archivo de imagen en el que queremos que se almacene el resultado. Si sólo queremos incluir los modelos de algunas aplicaciones podemos hacerlo con el siguiente comando:
./manage.py graph_models app1 app2 app3 -o mis_modelos.png
Este ejemplo es de los modelos de la PyCon-Tech, un framework de gestión de conferencias basado en Django:

Publicado por Antonio Melé el Sunday 12 de July de 2009 | 0 comentarios | Categorías: aplicaciones, imágenes, modelos, pluggables, trucos, tutorial
Muchas veces nos gustaría crear comandos propios que puedan ejecutarse mediante django-admin.py ó el manage.py de nuestro proyecto. Django permite crear comandos de administración específicos para cada aplicación de nuestro proyecto.
Para programar comandos de una aplicación, dentro de la carpeta de la aplicación debemos crear un directorio llamado management y dentro de éste otro llamado commands. Obviamente, para que funcionen los comandos, debemos asegurarnos de que nuestra aplicación está incluída en el setting INSTALLED_APPS. También debemos incluir un archivo __init__.py vacío en cada directorio que hemos creado (para que el directorio se interprete como un módulo de Python). Dentro de commands incluiremos un archivo .py por cada comando que deseemos utilizar para nuestra aplicación, quedando finalmente una estructura como esta:
mi_aplicacion/
__init__.py
models.py
management/
__init__.py
commands/
__init__.py
un_comando.py
otro_comando.py
views.py
El nombre que tenga cada archivo .py dentro de commands será el nombre del comando. Si por ejemplo creamos un archivo enviar.py, nuestro código se ejecutará cuando se utilice el comando manage.py enviar. Dentro de cada archivo de comando tenemos que crear una clase Command que herede alguna de las clases básicas de comandos.
Todas las clases básicas de comandos heredan de django.core.management.base.BaseCommand. Tu comando puede heredar directamente la clase BaseCommand pero hay otras clases de comandos que permiten crear distintos tipos de comando de una forma más sencilla:
Facilita la creación de comandos de administración que reciben una lista de nombres de aplicaciones Django como argumento y que hacen algo con cada uno de los nombres de las aplicaciones. El comando sqlall de Django funciona de esta manera.
Hace lo mismo que AppCommand pero la lista de argumentos que recibe puede ser cualquier cosa y no sólo nombres de aplicaciones. El comando startproject utiliza esto para recibir como parámetro el nombre o nombres de proyectos a crear.
Es lo más útil para crear comandos sencillos que no reciben ningún argumento. Un ejemplo de comando basado en NoArgsCommand es el conocido syncdb que utilizamos para sincronizar nuestros modelos con la base de datos.
Vamos a ver cómo crear un comando sencillo sin entrada de parámetros. Para ello utilizamos NoArgsCommand:
# -*- encoding: utf-8 -*-
from django.core.management.base import NoArgsCommand
class Command(NoArgsCommand):
help = "Breve descripción de lo que hace el comando."
def handle_noargs(self, **options):
# aquí va el código de mi comando
print 'Comando ejecutado'
Si necesitamos automatizar nuestro comando para que se ejecute automáticamente cada un intervalo de tiempo determinado podemos utilizar django-chronograph, del que ya hablamos anteriormente en este blog.
Puedes ver ejemplos de comandos que implementa Django en django.core.management.commands. También te será util leer el gran artículo de B-List sobre comandos de administración.
Publicado por Antonio Melé el Tuesday 19 de May de 2009 | 0 comentarios | Categorías: admin, comandos, tutorial
Actualización/Update: Zack translated this post into english and it is available here.
A veces tenemos que modificar información relativa a dos o más modelos distintos desde un solo formulario HTML. Es algo común por ejemplo cuando definimos un perfil de usuario y necesitamos que se pueda modificar la información del modelo User del sistema de autenticación de Django y la información de nuestro modelo de perfil simultáneamente. Vamos a ver cómo puede hacerse. Para seguir este ejemplo necesitaremos tener django.contrib.auth entre las aplicaciones instaladas de nuestro proyecto (setting INSTALLED_APPS).
Suponemos un modelo Perfil como el siguiente definido en nuestro models.py:
from django.db import models
class Perfil(models.Model):
user = models.OneToOneField(User, unique=True, related_name='perfil')
telefono = models.PositiveIntegerField()
direccion = models.TextField()
A continuación creamos un ModelForm para este modelo Perfil y otro para el modelo User del sistema de autenticación de Django. Más adelante usaremos conjuntamente ambos ModelForms en un único formulario HTML. Guardamos el siguiente código en forms.py:
from django import forms
from models import Perfil
from django.contrib.auth.models import User
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email')
class PerfilForm(forms.ModelForm):
class Meta:
model = Perfil
Como podemos ver sólo queremos editar los campos username, first_name, last_name y email del modelo User.
Ahora creamos la vista que generará el formulario para editar el perfil de un usuario. Para ello necesitaremos crear una instancia de los dos ModelForms que hemos definido anteriormente. Nuestro views.py debe tener la siguiente pinta:
from django.shortcuts import render_to_response
from django.template import RequestContext, loader
from django.contrib.auth.decorators import login_required
from forms import PerfilForm, UserForm
@login_required
def editar_perfil(request):
if request.method == 'POST':
# formulario enviado
user_form = UserForm(request.POST, instance=request.user)
perfil_form = PerfilForm(request.POST, instance=request.user.perfil)
if user_form.is_valid() and perfil_form.is_valid():
# formulario validado correctamente
user_form.save()
perfil_form.save()
return HttpResponseRedirect('/formulario-guardado/')
else:
# formulario inicial
user_form = UserForm(instance=request.user)
perfil_form = PerfilForm(instance=request.user.perfil)
return render_to_response('editar_perfil.html', { 'user_form': user_form, 'perfil_form': perfil_form }, context_instance=RequestContext(request))
Utilizamos el decorator @login_required ya que nuestros usuarios deberán estar autenticados para poder modificar su perfil. Si la petición llega por el método POST significa que se ha enviado el formulario y creamos dos Forms, uno para el modelo de usuario y otro para el del perfil, a partir de los datos recibidos. Validamos ambos formularios para guardarlos al igual que hacemos normalmente con un sólo formulario. Utilizamos una plantilla llamada editar_perfil.html a la que le pasamos ambos formularios a través de las variables user_form y perfil_form. El formulario de nuestra plantilla HTML será así de sencillo:
<form action="" method="post">
{{ user_form }}
{{ perfil_form }}
<input type="submit" value="Guardar cambios">
</form>
Con esto generaremos un formulario HTML que tiene primero los campos del modelo User seguidos por los campos del modelo Perfil asociado y que guardará correctamente cualquier cambio realizado en cualquiera de los dos objetos.
Publicado por Antonio Melé el Monday 6 de April de 2009 | 3 comentarios | Categorías: auth, forms, trucos, tutorial
Suscríbete a nuestro feed RSS y al feed de la comunidad para estar al tanto de todo lo que ocurre entorno a Django.
Tú también puedes escribir en éste blog. Para hacerlo basta con que nos digas sobre qué quieres escribir un artículo relacionado con Django.
Utilizar un formulario para modificar 2 modelos
Descubriendo objetos similares por sus etiquetas