User Tools

Site Tools


informatica:linux:django

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
informatica:linux:django [2014/03/05 17:06] – [Internacionalizacion] javiinformatica:linux:django [2019/05/19 16:55] – [Activar la interfaz administrativa] javi
Line 2: Line 2:
  
 django python framework django python framework
 +
 +===== Instalacion =====
 +
 +1. Instalar pip
 +
 +  sudo aptitude update; sudo aptitude install python-pip
 +  
 +2. Instalar ultima version de django:
 +
 +  sudo pip install Django==1.8
  
 ===== Primeros pasos ===== ===== Primeros pasos =====
Line 91: Line 101:
   python manage.py runserver 0.0.0.0:8080   python manage.py runserver 0.0.0.0:8080
  
-===== Activar la interfaz administrativa =====+===== Interfaz administrativa ===== 
 + 
 +Ahora la interfaz administrativa se activa por defecto 
 + 
 +==== Crear superusuario ==== 
 + 
 +https://docs.djangoproject.com/en/2.2/ref/django-admin/#django-admin-createsuperuser 
 + 
 +==== (Deprecated) Activar la interfaz administrativa =====
  
 1 1
Line 259: Line 277:
 ===== Archivos estaticos ===== ===== Archivos estaticos =====
  
-TODO+**OJO** cuando ejecutamos el servidor de desarrollo, todo funciona magicamente. Pero cuando estamos en produccion probablemente serviremos los archivos desde Apache, lo que requiere configuracion adicional para los archivos estaticos
  
-  python manage.py collectstatic+https://docs.djangoproject.com/en/1.6/howto/static-files/deployment/#serving-the-site-and-your-static-files-from-the-same-server
  
-===== Consultas =====+https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/modwsgi/#serving-files
  
-QuerySet+1. Creamos el directorio desde donse se van a servir los archivos estaticos. Puede estar fuera del DocumentRoot de Apache
  
-  Tabla1.objects.filter(pub_date__year=2006) +  mkdir /tmp/static 
-   +    
-===== Instalacion manual =====+2. Definir la variable "STATIC_ROOT" en el archivo "settings.py" del proyecto de django:
  
-1. Download the latest release from our download page.+<code> 
 +vim /srv/www/docroot/project1/project1/settings.py
  
-2Untar the downloaded file (e.gtar 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.+... 
 +STATIC_ROOT = '/tmp/static/' 
 +...  
 +</code>
  
-3. Change into the directory created in step 2 (e.g. cd Django-X.Y).+3. Entramos en el site de django y ejecutamos un comando para copiar todos los archivos estaticos a ese directorio:
  
-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.+<code> 
 +cd /srv/www/docroot/project1 
 +python manage.py collectstatic
  
-  python setup.py install+You have requested to collect static files at the destination 
 +location as specified in your settings.
  
 +This will overwrite existing files!
 +Are you sure you want to do this?
 +
 +Type 'yes' to continue, or 'no' to cancel: yes
 +Copying '/usr/local/lib/python2.7/dist-packages/django/contrib/admin/static/admin/css/login.css'
 +...
 +</code>
 +
 +Al final tenemos en "/tmp/static" todo un arbol con archivos estaticos (CSS, js, etc...)
 +
 +4. Anyadir la entrada al VirtualHost de Apache (version < 2.4):
 +
 +<code>
 +...
 +        Alias /static/ /tmp/static/
 +        <Directory /tmp/static>
 +                # Apache < 2.4
 +                Order deny,allow
 +                Allow from all
 +        </Directory>
 +...
 +</code>
 +
 +Para Apache >= 2.4:
 +
 +<code>
 +...
 +        Alias /static/ /tmp/static/
 +        <Directory /tmp/static>
 +                # Apache >= 2.4
 +                Require all granted
 +        </Directory>
 +...
 +</code>
 +
 +5. Recargar la configuracion de Apache para que los cambios tomen efecto:
 +
 +  sudo service apache2 reload
 +===== Consultas =====
 +
 +QuerySet
 +
 +  Tabla1.objects.filter(pub_date__year=2006)
 +  
 ===== Ejemplo aplicacion sin BBDD ===== ===== Ejemplo aplicacion sin BBDD =====
  
Line 446: Line 515:
 } }
 ... ...
 +</code>
 +
 +Flujo habitual para mantener el modelo:
 +
 +<code>
 +1. Change your models (in **models.py**).
 +2. Run **python manage.py makemigrations** to create migrations for those changes
 +3. Run **python manage.py migrate** to apply those changes to the database.
 </code> </code>
  
Line 532: Line 609:
      
 ===== Internacionalizacion ===== ===== Internacionalizacion =====
 +
 +==== Flujo de trabajo tipico ====
  
 https://docs.djangoproject.com/en/1.6/topics/i18n/translation/#url-internationalization https://docs.djangoproject.com/en/1.6/topics/i18n/translation/#url-internationalization
Line 559: Line 638:
 </code> </code>
  
-  * Requisitos para habilitar internacionalizacion:+1) Requisitos para habilitar internacionalizacion:
 <code> <code>
 project1/settings.py project1/settings.py
Line 576: Line 655:
 </code> </code>
  
-  * Ejemplo de archivo de texto donde se definen las variables traducir:+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: 
 +<code> 
 +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) 
 +</code> 
 + 
 +  * Ejemplo de uso en template (translation string "hello_world"): 
 +<code> 
 +{% load i18n %} 
 + 
 +{% trans "hello_world" as hello_world %} 
 + 
 +<p>{{ hello_world }}</p> 
 +</code> 
 + 
 +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: 
 + 
 +<code> 
 +django-admin.py makemessages -a 
 +processing locale en 
 +processing locale es 
 +processing locale ca 
 +</code> 
 + 
 +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: 
 <code> <code>
 app1/locale/es/LC_MESSAGES/django.po app1/locale/es/LC_MESSAGES/django.po
Line 600: Line 718:
  
 #: views.py:43 #: views.py:43
-msgid "Hello+msgid "hello_world
-msgstr "Hola en catala"+msgstr "Hola mundo"
 </code> </code>
  
-  Para generar esos archivos para todos los idiomas previamente definidos segun el arbol anterior: +**TODO**eliminar las lineas que contengan la palabra fuzzy
-<code> +
-django-admin.py makemessages -a +
-processing locale en +
-processing locale es +
-processing locale ca +
-</code>+
  
-  * Una vez editados los .po para generar los binarios, los .mo:+6. Una vez editados los .po para generar los binarios, los .mo:
 <code> <code>
 django-admin.py compilemessagesprocessing file django.po in /srv/www/incasol/incasolproj/invoices/locale/en/LC_MESSAGES django-admin.py compilemessagesprocessing file django.po in /srv/www/incasol/incasolproj/invoices/locale/en/LC_MESSAGES
Line 620: Line 732:
 **IMPORTANTE**: tras compilar mensajes hay que reiniciar el servidor de paginas web para que los cambios tomen efecto **IMPORTANTE**: tras compilar mensajes hay que reiniciar el servidor de paginas web para que los cambios tomen efecto
  
-  * Ejemplo de uso en vista: +7. Reiniciar el servidor de paginas web para que tome los cambios efectuados en los archivos .po
-<code> +
-app1/views.py+
  
-from django.template import RequestContext +==== Vista ya creada para cambiar el idioma ====
-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"),' - ',  request.LANGUAGE_CODE +
-    return HttpResponse(output) +
-</code> +
- +
-  * Ejemplo de uso en template: +
-<code> +
-{% load i18n %} +
- +
-{% trans "invoice_query" as invoice_query %} +
- +
-<p>{{ invoice_query }}</p> +
-</code>+
  
 En este ejemplo cambiamos el lenguaje en una vista en funcion de un parametro que llega via GET: En este ejemplo cambiamos el lenguaje en una vista en funcion de un parametro que llega via GET:
Line 679: Line 772:
  
   python -c "import tempfile; print tempfile.gettempdir()"   python -c "import tempfile; print tempfile.gettempdir()"
 +  
 +===== LDAP =====
 +
 +pythonhosted.org/django-auth-ldap
 +
 +1. Instalar modulo:
 +
 +  sudo aptitude install python-ldap
 +  sudo pip install django-auth-ldap
 +
 +2. Editar settings:
 +
 +<code>
 +docroot/project1/project1/settings.py
 +
 +# LDAP
 +import ldap
 +from django_auth_ldap.config import LDAPSearch
 +AUTHENTICATION_BACKENDS = (
 +    'django_auth_ldap.backend.LDAPBackend',
 +)
 +AUTH_LDAP_SERVER_URI = "ldaps://ldap.example.com"
 +AUTH_LDAP_BIND_DN = "cn=readonly,dc=example,dc=com"
 +AUTH_LDAP_BIND_PASSWORD = "secret"
 +#AUTH_LDAP_START_TLS = True
 +AUTH_LDAP_USER_SEARCH = LDAPSearch("dc=example,dc=com", ldap.SCOPE_SUBTREE,
 +                                   "(uid=%(user)s)")
 +# LDAP groups
 +from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
 +AUTH_LDAP_GROUP_SEARCH = LDAPSearch("ou=groups,dc=example,dc=com",
 +    ldap.SCOPE_SUBTREE, "(objectClass=groupOfNames)"
 +)
 +AUTH_LDAP_GROUP_TYPE = GroupOfNamesType()
 +AUTH_LDAP_REQUIRE_GROUP = "cn=ldapgroup1,ou=groups,dc=example,dc=com"
 +</code>
 +
 +En este ejemplo nos conectamos via TLS al servidor LDAP "ldap.example.com" y requerimos que el usuario pertenezca al grupo "ldapgroup1", que es un objeto LDAP de tipo "groupOfNames"
 +
 +3. Crear el modelo de base de datos, si es que no lo estaba ya:
 +
 +<code>
 +cd docroot/project1; python manage.py syncdb
 +</code>
 +
 +Contestar a las preguntas.
 +
 +**TODO**: ver si hay alguna forma de evitar este paso, y que se almacenen todos los valores en sesiones.
 +**SOLUCION 1**: sobreescribir _LDAPUser._get_or_create_user() de "/usr/local/lib/python2.7/dist-packages/django_auth_ldap/backend.py"
 +**SOLUCION 2**: escribir nuestro propio backend tomando django_auth_ldap como ejemplo
 +
 +4. Ejemplo de formulario con validacion de usuario:
 +
 +<code>
 +from django.contrib.auth import authenticate
 +
 +def login(request):
 +    ''' Displays/process login form'''
 +    d = {}
 +    if request.method == 'POST': # If the form has been submitted...
 +        d['form'] = LoginForm(request.POST) # A form bound to the POST data
 +        if d['form'].is_valid(): # All validation rules pass
 +            # Process the data in form.cleaned_data
 +            username = d['form'].cleaned_data['username']
 +            password = d['form'].cleaned_data['password']
 +            user = authenticate(username=username, password=password)
 +            if user is not None:
 +                logger.info(user)
 +                return HttpResponse('Success')
 +                if user.is_active:
 +                    login(request, user)
 +                    return HttpResponse('Success')
 +                else:
 +                    return HttpResponse('Disabled account')
 +            else:
 +                return HttpResponse('Invalid login')
 +        else:
 +            d['result'] = "There was an error processing the form"
 +    else:
 +        d['form'] = LoginForm() # An unbound form
 +    return render_to_response('login.html',d,\
 +           context_instance=RequestContext(request))
 +</code>
 +
 +Falta el template y el resto de la vista. Es solo un ejemplo
 +
 +===== Errores =====
 +
 +==== The password is too similar to the username. ====
 +
 +En realidad no es un error, es solo para documentar un atajo para evitar esta restricción a la hora de especificar una contraseña para un nuevo usuario desde la interfaz gráfica del módulo admin.
 +
 +https://stackoverflow.com/a/35330167
 +
 +1. Crear el usuario desde el admin:
 +
 +http://localhost:8000/admin/auth/user/add/
 +
 +2. Iniciar shell
 +
 +  cd /path/django && python manage.py shell
 +  
 +3. Cambiar la contraseña de ese usuario, en este ejemplo "your_user":
 +
 +<code>
 +from django.contrib.auth.models import User
 +user = User.objects.get(username='your_user')
 +user.set_password('simple')
 +user.save()
 +</code>
 +
 +====  Error al crear app ====
 +
 +Comando:
 +
 +<code>
 +python manage.py startapp app1
 +</code>
 +
 +Error:
 +
 +<code>
 +  File "manage.py", line 16
 +    ) from exc
 +         ^
 +SyntaxError: invalid syntax
 +</code>
 +
 +Solución:
 +
 +<code>
 +python3 manage.py startapp app1
 +</code>
informatica/linux/django.txt · Last modified: 2019/05/19 16:55 by javi