This is an old revision of the document!
−Table of Contents
Django
django python framework
Primeros pasos
/srv/www/docroot
1. Crear proyecto:
django-admin.py startproject project1
└── project1 ├── manage.py └── project1 ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py
2. Motor SGBD
vim settings.py
3. Crear aplicacion:
cd project python manage.py startapp app1
├── app1 │ ├── admin.py │ ├── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py ├── manage.py └── project1 ├── __init__.py ├── __init__.pyc ├── settings.py ├── settings.pyc ├── urls.py └── wsgi.py
4. Crear modelos:
A mano:
vim app1/models.py
O 'extraerlo' de una bd ya existente. Luego hay que pulir un poco:
python manage.py inspectdb >> app1/models.py
5. Activar modelo (seccion 'INSTALLED_APPS')
vim settings.py INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', # Uncomment the next line to enable the admin: 'django.contrib.admin', # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs', 'app1', )
6. Crear bd y tablas:
python manage.py syncdb
7. Ingesta:
python manage.py loaddata app1/sql/regional.csv.json
8. Arrancar el servido:
python manage.py runserver 0.0.0.0:8080
Activar la interfaz administrativa
1
vim settings.py
Descomentar 'django.contrib.admin' en 'INSTALLED_APPS'
2
python manage.py syncdb
3
vim urls.py
Descomentar las siguientes lineas:
from django.contrib import admin admin.autodiscover() (r'^admin/', include(admin.site.urls)),
Activar la interfaz administrativa en app1 y tabla 'Tabla1'
2.1 Crear:
vim app1/admin.py
Con el siguiente contenido:
from app1.models import Tabla1 from django.contrib import admin admin.site.register(Tabla1)
Django + nginx
1. Instalar paquetes:
sudo aptitude install python-flup nginx
2. Configurar nginx:
sudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.old sudo vim /etc/nginx/nginx.conf
user javi javi; worker_processes 2; error_log /var/log/nginx/error_log info; events { worker_connections 1024; use epoll; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $bytes_sent ' '"$http_referer" "$http_user_agent" ' '"$gzip_ratio"'; client_header_timeout 10m; client_body_timeout 10m; send_timeout 10m; connection_pool_size 256; client_header_buffer_size 1k; large_client_header_buffers 4 2k; request_pool_size 4k; gzip on; gzip_min_length 1100; gzip_buffers 4 8k; gzip_types text/plain; output_buffers 1 32k; postpone_output 1460; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 75 20; ignore_invalid_headers on; index index.html; server { listen 80; server_name localhost; location /media { root /srv/test.facsimile/branches/1.1/proyecto2/media; } location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|mov) { access_log off; expires 30d; } location / { # host and port to fastcgi server fastcgi_pass 0.0.0.0:8080; fastcgi_param PATH_INFO $fastcgi_script_name; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param QUERY_STRING $query_string; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_pass_header Authorization; fastcgi_intercept_errors off; } access_log /var/log/nginx/localhost.access_log main; error_log /var/log/nginx/localhost.error_log; } }
Parametros a cambiar:
-Usuario que ejecuta nginx:
user javi javi;
-(Opcional) ruta a directorios multimedia (se puede eliminar)
server_name localhost; location /media { root /srv/test.facsimile/branches/1.1/proyecto2/media; }
- Direccion ip y puerto en el que escucha django
fastcgi_pass 0.0.0.0:8080;
3. Arrancar django
Suponiendo que el directorio donde este el proyecto sea '/srv/test.facsimile/branches/1.1/proyecto2/':
cd /srv/test.facsimile/branches/1.1/proyecto2/; python manage.py runfcgi method=threaded host=0.0.0.0 port=8080
4. Arrancar nginx:
sudo /etc/init.d/nginx start
5. Probar:
http://localhost/accion_1
Nginx redirige la peticion a:
http://localhost:8080/accion_1
Archivos estaticos
TODO
python manage.py collectstatic
Consultas
QuerySet
Tabla1.objects.filter(pub_date__year=2006)
Instalacion manual
1. Download the latest release from our download page.
2. Untar the downloaded file (e.g. tar xzvf Django-X.Y.tar.gz, where X.Y is the version number of the latest release). If you're using Windows, you can download the command-line tool bsdtar to do this, or you can use a GUI-based tool such as 7-zip.
3. Change into the directory created in step 2 (e.g. cd Django-X.Y).
4. If you're using Linux, Mac OS X or some other flavor of Unix, enter the command sudo python setup.py install at the shell prompt. If you're using Windows, start a command shell with administrator privileges and run the command python setup.py install. This will install Django in your Python installation's site-packages directory.
python setup.py install
Ejemplo aplicacion sin BBDD
1. Nos metemos dentro de un directorio fuera del docroot de apache:
cd /srv
2. Creamos el proyecto (utilizo sudo porque no tengo permisos en este directorio):
sudo django-admin.py startproject sms_project sudo chown -R usuario:usuario sms_project
3. Creamos la app:
cd /srv/sms_project python manage.py startapp sms_app
4. Creamos una vista por defecto (hello world). Editamos:
vim /srv/sms_project/sms_app
Y la dejamos tal que asi:
from django.http import HttpResponse def index(request): return HttpResponse("Hello, world. You're at the sms index.")
5. Creamos una regla para que por defecto todas las peticiones que apunten a 'sms_app' muestren la vista 'index'. Editamos:
vim /srv/sms_project/sms_app/urls.py
Y la dejamos tal que asi:
from django.conf.urls import patterns, url from sms_app import views urlpatterns = patterns('', url(r'^$', views.index, name='index') )
6. Creamos una regla para que cuando el servidor web reciba peticiones para “sms_app/” cargue el modulo “/srv/sms_project/sms_app/urls.py”
Editamos:
vim /srv/sms_project/sms_project/urls.py
Y la dejamos tal que asi:
from django.conf.urls import patterns, include, url urlpatterns = patterns('', url(r'^sms_app/', include('sms_app.urls')), )
7. Arrancamos el servidor de prueba:
cd /srv/sms_project; python manage.py runserver
8. Pedimos una pagina web:
elinks http://localhost:8000/sms/sms_app/
Deberia responder:
Hello, world. You're at the sms index.
Apache mod_wsgi
Configuracion general de apache. Escenario:
/srv/www/docroot | Document root |
/srv/www/docroot/project1 | Proyecto django |
/srv/www/docroot/project1/project1/wsgi.py | Creado al ejecutar “django-admin.py startproject project_tracker” |
1. Instalar libapache2-mod-wsgi:
sudo aptitude update; sudo aptitude install libapache2-mod-wsgi
2. Habilitar modulo:
sudo a2enmod wsgi
3. Deshabilitar sitio por defecto:
sudo a2dissite 000-default
4. Crear un nuevo sitio:
sudo vim /etc/apache2/sites-available/django
Y dejarlo tal que asi:
<VirtualHost *:443> ServerName django.example.com ServerAdmin webmaster@localhost DocumentRoot /srv/www/docroot SSLEngine on SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key WSGIScriptAlias / /srv/www/docroot/project1/project1/wsgi.py WSGIDaemonProcess django.example.com python-path=/srv/www/docroot/project1:/usr/local/lib/python2.7/site-packages WSGIProcessGroup django.example.com <Directory /srv/www/docroot/project1> <Files wsgi.py> Order deny,allow #Require all granted Allow from all </Files> </Directory> ErrorLog ${APACHE_LOG_DIR}/django.example.com.error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog ${APACHE_LOG_DIR}/django.example.com.access.log combined </VirtualHost>
5. Habilitar el sitio:
sudo a2ensite django
6. Recargar apache:
sudo /etc/init.d/apache2 reload
Base de datos
Lo primero configurar la BD:
vim /srv/www/docroot/project1/project1/settings.py
Y editar las siguientes lineas:
... DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'. 'NAME': 'django', # Or path to database file if using sqlite3. 'USER': 'asterisk', # Not used with sqlite3. 'PASSWORD': 'xxxxxx', # Not used with sqlite3. 'HOST': 'mysql-1.dev.jj.com', # Set to empty string for localhost. Not used with sqlite3. 'PORT': '', # Set to empty string for default. Not used with sqlite3. } } ...
django -> SGBD
Crea BBDD y las tablas a partir del modelo. Si 'model.py' no existe y se habilita el sistema de autenticacion de Django creara unas tablas:
cd /srv/sms_project; python manage.py syncdb
Creating tables ... Creating table auth_permission Creating table auth_group_permissions Creating table auth_group Creating table auth_user_user_permissions Creating table auth_user_groups Creating table auth_user Creating table django_content_type Creating table django_session Creating table django_site
Crear cuenta superusuario:
You just installed Django's auth system, which means you don't have any superusers defined. Would you like to create one now? (yes/no): yes Username (leave blank to use 'usuario'): E-mail address: javi@legido.com Password: Password (again): Superuser created successfully.
SGBD -> django
AVISO: sobreescribiremos el archivo ya existente. Si queremos crear el modelo a partir de una BBDD que ya exista:
cd /srv/www/docroot/project1; python manage.py inspectdb >> app1/models.py
NOTA: si la BBDD es muy compleja probablemente habra que retocar 'model.py' (tipicamente cambiar el orden de las clases)
Django API
cd /srv/sms_project; python manage.py shell
Autenticacion
https://docs.djangoproject.com/en/dev/topics/auth/?from=olddocs#built-in-forms
https://docs.djangoproject.com/en/dev/topics/auth/customizing/
https://docs.djangoproject.com/en/1.4/howto/auth-remote-user/
Templates
1. Incluir la app en settings:
vim /srv/www/docroot/project1/project1/settings.py
Y anyadir la siguiente linea en “INSTALLED_APPS”:
INSTALLED_APPS = ( ... 'app1', )
2. Ejemplo de uso:
/srv/www/docroot/project1/app1/views.py
def invoice_query(request): ... return render_to_response('template1.html',d,\ context_instance=RequestContext(request))
Que tomara la plantilla de la siguiente ruta:
/srv/www/docroot/project1/app1/templates/template1.html
Internacionalizacion
Flujo de trabajo tipico
https://docs.djangoproject.com/en/1.6/topics/i18n/translation/#url-internationalization
- Estructura de archivos implicados en la internacionalizacion:
. +-- project1 | +-- __init__.py | +-- settings.py | +-- urls.py | +-- wsgi.py +-- app1 | +-- admin.py | +-- forms.py | +-- __init__.py | +-- locale | | +-- es | | +-- LC_MESSAGES | | +-- django.mo | | +-- django.po | +-- models.py | +-- tests.py | +-- urls.py | +-- views.py +-- manage.py
1) Requisitos para habilitar internacionalizacion:
project1/settings.py ... INSTALLED_APPS = ( ... 'app1', ) MIDDLEWARE_CLASSES = ( ... 'django.middleware.locale.LocaleMiddleware', ) USE_I18N = True USE_L10N = True
2. Crear translation strings con el identificador que se va a usar luego en los message file (uno por cada idioma) para traducir la cadena.
- Ejemplo de uso en vista (translation string “hello_world”). Hemos usado el alias _, muy usado:
app1/views.py from django.template import RequestContext from django.shortcuts import render_to_response from django.http import HttpResponseRedirect, HttpResponse from django.utils.translation import ugettext as _ def test(request, ): output = _("hello_world"),' - ', request.LANGUAGE_CODE return HttpResponse(output)
- Ejemplo de uso en template (translation string “hello_world”):
{% load i18n %} {% trans "hello_world" as hello_world %} <p>{{ hello_world }}</p>
3. Crear la estructura de directorios (el archivo .po de momento no hace falta) adecuados (ver arbol al inicio de esta seccion). Por ejemplo:
mkdir -p locale/es/LC_MESSAGES
4. Crear de forma automatica los message files para todas las lenguas que tienen directorio:
django-admin.py makemessages -a processing locale en processing locale es processing locale ca
5. Ahora tenemos los .po creados de forma automatica para todos los idiomas, cada uno de los cuales con sus trasnlation string. Ahora tenemos que completar el campo “msgstr” para cada una de las translation string con la traduccion. Ejemplo de archivo .po:
app1/locale/es/LC_MESSAGES/django.po # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-02-18 08:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: views.py:43 msgid "hello_world" msgstr "Hola mundo"
TODO: eliminar las lineas que contengan la palabra fuzzy
6. Una vez editados los .po para generar los binarios, los .mo:
django-admin.py compilemessagesprocessing file django.po in /srv/www/incasol/incasolproj/invoices/locale/en/LC_MESSAGES processing file django.po in /srv/www/project/project/app/locale/es/LC_MESSAGES processing file django.po in /srv/www/project/project/app/locale/ca/LC_MESSAGES
IMPORTANTE: tras compilar mensajes hay que reiniciar el servidor de paginas web para que los cambios tomen efecto
7. Reiniciar el servidor de paginas web para que tome los cambios efectuados en los archivos .po
Vista ya creada para cambiar el idioma
En este ejemplo cambiamos el lenguaje en una vista en funcion de un parametro que llega via GET:
http://example.com?newLang=ca app1/views.py
from django.template import RequestContext from django.shortcuts import render_to_response from django.http import HttpResponseRedirect, HttpResponse from invoices.models import Expedient, RawSqlQueries from forms import InvoiceForm from django.utils.translation import ugettext as _, activate def test(request): lang = request.GET.get('newLang') activate(lang) output = _("Hello"),' - ', request.LANGUAGE_CODE, ' - ',\ request.session['django_language'] return HttpResponse(output)
Sesiones
https://docs.djangoproject.com/en/dev/topics/http/sessions/
- En archivos
docroot/project1/project1/settings.py
SESSION_ENGINE = "django.contrib.sessions.backends.file"
Para saber el directorio por defecto donde almacena los archivos temporales, siempre que 'SESSION_FILE_PATH' NO se haya especificado:
python -c "import tempfile; print tempfile.gettempdir()"