source: sapic/curso_django/curso_django.tex @ 7522254

erwin
Last change on this file since 7522254 was 8b11e21, checked in by lhernandez <lhernandez@…>, 7 años ago

Agregado banner

  • Propiedad mode establecida a 100644
File size: 65.8 KB
Línea 
1\documentclass[xcolor=dvipsnames]{beamer}
2<<<<<<< HEAD
3\usetheme{Berkeley}
4\usepackage[spanish]{babel}
5\usepackage[utf8]{inputenc}
6\usepackage[T1]{fontenc}
7\usepackage{lmodern}
8\usepackage{fancyhdr}
9\usepackage{graphicx}
10\usepackage{mathrsfs}
11\usepackage{amsmath}
12\usepackage{lmodern}
13\usepackage{multimedia}
14\usepackage{hyperref}
15\usepackage{varioref}
16\usepackage{ragged2e}
17\usepackage{etoolbox}
18\usepackage{lipsum}
19\usepackage{fancyvrb}
20\fvset{fontsize=\footnotesize}
21\RecustomVerbatimEnvironment{verbatim}{Verbatim}{}
22\apptocmd{\frame}{}{\justifying}{} % Allow optional arguments after frame.
23\usecolortheme[{rgb={0.6,0,0}}]{structure}
24\setbeamercovered{transparent}
25\setbeamertemplate{items}[ball]
26\setbeamertemplate{blocks}[rounded][shadow=true]
27\beamertemplateshadingbackground{gray!50}{white!50}
28\newtheorem{Ejemplo}{Django}
29\useoutertheme{infolines}
30\title []{Framework Django 1.11}
31\author{Instructor Ing. Erwin Paredes}
32%\logo{ \includegraphics[height=3cm]{figura/logo-blanco2.png}}
33\institute{CENDITEL}
34\date{\today}
35
36\begin{document}
37
38\section{Cenditel}
39\begin{frame}
40\maketitle
41\end{frame}
42
43\subsection{La Fundación}
44\begin{frame}
45\begin{block}{Fundación CENDITEL}
46\indent   
47Somos el Centro Nacional de Desarrollo e Investigación en Tecnologías Libres, cuyas actividades son el desarrollo de proyectos con impacto tecnológico enmarcados en las áreas de Software, Hardware y Telecomunicaciones.
48https://www.cenditel.gob.ve
49
50\end{block}
51\end{frame}
52
53\subsection{Finalidad del Curso}
54\begin{frame}
55\begin{block}{Finalidad}
56     
57Consolidar la comunidad de desarrollo en software libre alrededor de la tecnología, en este caso el framework de desarrollo Django del lenguaje de programación Python
58\end{block}
59\end{frame}
60
61\subsection{Contenido del Curso}
62\begin{frame}
63\begin{block}{Contenido del Curso}
64\begin{itemize}
65\item 
66Introducción
67\item 
68Configurar ambiente de trabajo
69\item 
70Crear proyecto
71\item 
72Crear aplicaciones y estructura del proyecto
73\item 
74Modelos y migraciones
75\item 
76Relaciones
77\item 
78Django shell y Querysets
79\item 
80Configurar URLs y primera views
81\item 
82Sistema de plantillas
83\item 
84Configurar archivos estáticos
85\item 
86Listar Registros
87\item 
88Formularios y vista para anexar registros
89\item 
90Vistas para modificar y eliminar registros
91\end{itemize}
92\end{block}
93\end{frame}
94
95
96\begin{frame}
97\begin{block}{Contenido del Curso}
98\begin{itemize}
99\item
100ListView, CreateView, UpdateView, DeleteView   
101\item
102Crear Login
103\item
104Registro de Usuarios
105\item
106Decorador Login required
107\item
108Recuperar contraseña por correo
109\item
110Introducción a conceptos avanzados
111\end{itemize}
112\end{block}
113\end{frame}
114
115
116
117\section{Django}
118\subsection{Introducción}
119\begin{frame}
120Django: Es un entorno de trabajo para el desarrollo Web, basado en el lenguaje de programación Python.
121
122Un entorno de trabajo o framework, implica una estructura conceptual y conjunto de herramientas que típicamente son un conjunto de librerías, que permite organizar el desarrollo.
123
124Para el framework Django la estructura conceptual es el denominado MVC (Modelo Vista Controlador), esto es, se organiza el desarrollo en módulos que separan el modelo de datos, la interfaz o vista y el comportamiento.
125
126Por lo que para cada aplicación o módulo que conforma el proyecto se agrupa en lo siguientes archivos:
127
128\begin{itemize}
129 \item models.py :Contiene las clases que definen la estructura de datos
130 \item views.py  :Contiene la codificación de las funcionalidades que permiten controlar el comportamiento del sistema.
131 \item *.html    :Contiene la codificación de la interfaz
132\end{itemize}
133\end{frame}
134
135\subsection{Configurar ambiente de trabajo}
136\begin{frame}[fragile]
137
138\begin{Large}\textbf{Sitio Oficial}\end{Large}
139\begin{verbatim}
140
141https://www.djangoproject.com/
142
143Instalación
144
145https://docs.djangoproject.com/en/1.11/intro/install
146
147Descarga:
148
149https://www.djangoproject.com/download/
150\end{verbatim}
151\end{frame}
152
153\begin{frame}[fragile]
154
155\begin{Large}\textbf{Instalación}\end{Large}
156\begin{verbatim}
157// Descomprimir el archivo
158
159tar -xzvf Django1.11.tar.gz
160
161cd Django1.11
162
163python setup.py install
164
165// Comprobar la instalación del framework:
166
167python
168import django
169django.VERSION
170
171Ctrl + D
172\end{verbatim}
173\end{frame}
174
175\subsection{Crear proyecto}
176\begin{frame}[fragile]
177
178\begin{verbatim}
179// Crear el primer proyecto:
180
181django-admin startproject curso
182
183// este comando crea la siguiente infraestructura
184de carpetas y archivos:
185
186curso/
187    manage.py
188    curso/
189        __init__.py
190        settings.py
191        urls.py
192        wsgi.py
193
194
195Configurar la base de datos
196
197\end{verbatim}
198\end{frame}
199
200\begin{frame}[fragile]
201
202\begin{verbatim}
203// Se debe haber instalado el gestor de la Base de
204Datos Postgresql  y la librería de conexión psycopg2
205// Creamos la base de datos:
206su postgres
207psql
208CREATE USER administrador;
209CREATE DATABASE curso;
210
211// Se edita el archivo curso/settings.py la constante
212DATABASES = {
213   'default': {
214        'ENGINE': 'django.db.backends.postgresql',
215        'NAME': 'curso',
216        'USER': 'administrador',
217        'PASSWORD': 'clave',
218        'HOST': '127.0.0.1',
219        'PORT': '5432',
220  } }
221\end{verbatim}
222\end{frame}
223
224\begin{frame}[fragile]
225\begin{verbatim}
226// Se guarda y ejecuta el siguiente comando para
227crear las tablas iniciales del proyecto:
228
229python manage.py migrate
230
231// Se ejcuta el comando para crear el superusuario o
232usuario administrador del proyecto:
233
234python manage.py createsuperuser
235
236// Se introducen los datos que solicita
237// Se ejecuta el siguiente comando para activar el
238servidor de prueba de forma local
239
240python manage.py runserver
241\end{verbatim}
242\end{frame}
243
244\begin{frame}[fragile]
245\begin{verbatim}
246python manage.py runserver
247
248// Arroja el siguiente mensaje
249Performing system checks...
250
251System check identified no issues (0 silenced).
252
253July 26, 2017 - 15:32:30
254Django version 1.11.3,using settings 'curso.settings'
255Starting development server at http://127.0.0.1:8000/
256Quit the server with CONTROL-C.
257
258// Abrimos el navegador de preferencia y colocamos la
259siguiente dirección para acceder al sistema
260administrativo del proyecto:
261
262http://localhost:8000/admin
263\end{verbatim}
264\end{frame}
265
266\subsection{Crear aplicaciones}
267\begin{frame}[fragile]
268\begin{verbatim}
269
270http://localhost:8000/admin
271
272// En el debemos autenticarnos con el usuario y
273password del superusuario creado en los pasos
274anteriores
275
276// Allí podemos gestionar los usuarios del sistema
277así como los grupos que evenctualmente se utilizan
278para asignar permisos de acceso.
279
280// En el terminal presionar las teclas Ctrl + C para
281interrumpir la ejecución del servidor y así crear
282las aplicaciones del proyecto.
283
284python manage.py startapp encuesta
285
286\end{verbatim}
287\end{frame}
288
289\subsection{Modelos}
290\begin{frame}[fragile]
291\begin{verbatim}
292python manage.py startapp encuesta
293
294// Se edita el archivo encuesta/models.py
295
296from django.db import models
297
298class Question(models.Model):
299    question_text = models.CharField(max_length=200)
300    pub_date =models.DateTimeField('date published')
301
302class Choice(models.Model):
303    question = models.ForeignKey(Question,
304               on_delete=models.CASCADE)
305    choice_text = models.CharField(max_length=200)
306    votes = models.IntegerField(default=0)
307
308\end{verbatim}
309\end{frame}
310
311\begin{frame}[fragile]
312\begin{verbatim}
313// Almacenamos y editamos el archivo
314curso/settings.py la constante:
315
316INSTALLED_APPS = [
317    ...
318    'django.contrib.staticfiles',
319    'encuesta',
320]
321
322// Para crear las tablas correspondiente de models.py
323se ejecuta el comando:
324
325python manage.py makemigrations encuesta
326
327python manage.py migrate encuesta
328
329\end{verbatim}
330\end{frame}
331
332\subsection{Relaciones}
333\begin{frame}[fragile]
334\begin{verbatim}
335// Para el manejo de las tablas por medio del
336framework se puede realizar desde el terminal
337con el comando:
338
339python manage.py shell
340
341
342\end{verbatim}
343\end{frame}
344
345\subsection{Django shell y Querysets}
346\begin{frame}[fragile]
347\begin{verbatim}
348
349// Allí podemos ejecutar las siguientes instrucciones
350
351from encuesta.models import Question, Choice
352from django.utils import timezone
353
354Question.objects.all()
355q = Question(question_text="Que hay de nuevo?",
356                     pub_date=timezone.now())
357q.save()
358q.id
359q.question_text
360q.pub_date
361q.question_text = "Q ai d nuevo?"
362q.save()
363
364Ctril + D para salir
365\end{verbatim}
366\end{frame}
367
368\begin{frame}[fragile]
369\begin{verbatim}
370Editamos nuevamente el archivo encuesta/models.py
371para añadir el sigueinte metodo a la clase Question
372
373import datetime
374
375from django.db import models
376from django.utils import timezone
377
378class Question(models.Model):
379    # ...
380    def was_published_recently(self):
381        return self.pub_date >= timezone.now() -
382                      datetime.timedelta(days=1)
383
384Guardamos y volvemos a terminal:
385
386python manage.py shell
387
388\end{verbatim}
389\end{frame}
390
391\begin{frame}[fragile]
392\begin{verbatim}
393from polls.models import Question, Choice
394
395Question.objects.all()
396q = Question.objects.get(pk=1)
397q.was_published_recently()
398
399q = Question.objects.filter(id=1)
400
401q = Question.objects.filter(
402          question_text__startswith='Q')
403
404from django.utils import timezone
405current_year = timezone.now().year
406Question.objects.get(pub_date__year=current_year)
407
408Question.objects.get(id=2) Error...
409\end{verbatim}
410\end{frame}
411
412\begin{frame}[fragile]
413\begin{verbatim}
414q = Question.objects.get(pk=1)
415q.choice_set.all()
416q.choice_set.create(choice_text='No mucho', votes=0)
417q.choice_set.create(choice_text='Muchas cosas'
418                                           ,votes=0)
419c = q.choice_set.create(choice_text='De todo un poco'
420                                           ,votes=0)
421
422c.question
423
424q.choice_set.all()
425q.choice_set.count()
426
427Crtl + D para salir
428
429\end{verbatim}
430\end{frame}
431
432\begin{frame}[fragile]
433\begin{verbatim}
434Incluir el modelo de la aplicación encuesta
435en el sistema admin:
436
437Editamos el archivo encuesta/admin.py
438from django.contrib import admin
439
440from .models import Question
441
442admin.site.register(Question)
443
444Guardamos y ejecutamos el servidor
445de prueba nuevamente:
446
447python manage.py runserver
448
449en el navegador http://localhost:8000/admin
450
451\end{verbatim}
452\end{frame}
453
454\subsection{Configurar URLs y primera views}
455\begin{frame}[fragile]
456\begin{verbatim}
457Crear la primera vista para acceso del proyecto
458Editamos el archivo encuesta/urls.py
459
460from django.conf.urls import url
461from . import views
462urlpatterns = [
463    # ex: /encueta/
464    url(r'^$', views.index, name='index'),
465    # ex: /encuesta/5/
466    url(r'^(?P<question_id>[0-9]+)/$',
467    views.detail, name='detail'),
468    # ex: /encuesta/5/results/
469    url(r'^(?P<question_id>[0-9]+)/results/$',
470    views.results, name='results'),
471    # ex: /encuesta/5/vote/
472    url(r'^(?P<question_id>[0-9]+)/vote/$',
473     views.vote, name='vote'),
474]
475\end{verbatim}
476\end{frame}
477
478\begin{frame}[fragile]
479\begin{verbatim}
480Editamos el archivo encuesta/views.py:
481
482from django.http import HttpResponse
483from .models import Question
484
485def index(request):
486    question_list = Question.objects.order_by('-pub_date')[:5]
487    output = ', '.join([q.question_text for q in question_list])
488    return HttpResponse(output)
489
490def detail(request, question_id):
491    return HttpResponse("Question No: %s." % question_id)
492
493def results(request, question_id):
494    response = "Results of question %s."
495    return HttpResponse(response % question_id)
496
497def vote(request, question_id):
498    return HttpResponse("Voting on question %s." % question_id)
499\end{verbatim}
500\end{frame}
501
502\begin{frame}[fragile]
503\begin{verbatim}
504Guardamos y ejecutamos el servidor de prueba y
505probamos los enlaces desde el navegador:
506
507python manage.py runserver
508
509En el navegador probamos los siguientes enlaces:
510
511http://localhost:8000/encueta
512http://localhost:8000/encueta/1
513http://localhost:8000/encueta/1/result
514http://localhost:8000/encueta/1/vote
515
516\end{verbatim}
517\end{frame}
518
519\subsection{Sistema de plantillas}
520
521\begin{frame}[fragile]
522\begin{verbatim}
523Uso del plantillas:
524
525Creamos la siguiente estructura
526
527cd encuesta
528mkdir templates
529mkdir templates/encuesta
530
531y editamos el archivo index.html allí
532
533gedit encuesta/templates/encuesta/index.html
534
535\end{verbatim}
536\end{frame}
537
538\begin{frame}[fragile]
539\begin{verbatim}
540{% if question_list %}
541    <ul>
542    {% for question in question_list %}
543        <li>
544         <a href="/encuesta/{{ question.id }}/">
545          {{
546            question.question_text
547          }}
548         </a>
549        </li>
550    {% endfor %}
551    </ul>
552{% else %}
553    <p>No hay encuestas.</p>
554{% endif %}
555\end{verbatim}
556\end{frame}
557
558\begin{frame}[fragile]
559\begin{verbatim}
560Guardamos y modificamos el archivo encuesta views.py
561para que utilice la plantilla
562
563from django.http import HttpResponse
564from django.template import loader
565
566from .models import Question
567
568
569def index(request):
570    question_list = Question.objects.order_by('-pub_date')[:5]
571    template = loader.get_template('polls/index.html')
572    context = {
573        'question_list': question_list,
574    }
575    return HttpResponse(template.render(context, request))
576
577\end{verbatim}
578\end{frame}
579
580\begin{frame}[fragile]
581\begin{verbatim}
582o utilizando la shortcuts render
583
584from django.shortcuts import render
585
586from .models import Question
587
588
589def index(request):
590    question_list = Question.objects.order_by('-pub_date')[:5]
591    context = {'question_list': question_list}
592    return render(request, 'polls/index.html', context)
593
594
595\end{verbatim}
596\end{frame}
597
598\subsection{Configurar estáticos}
599\begin{frame}[fragile]
600\begin{verbatim}
601Descargar plantillas prediseñadas, por ejemplo:
602
603https://adminlte.io/
604
605Copiar los directorios ccs y js en los en la carpeta static
606
607Copiar los archivo *.html en la carpeta templates
608
609Editar index.html y cambiar los enlaces a cada archivo en:
610
611<link rel="stylesheet"
612href="{% static 'css/DataTables/jquery.dataTables.min.css' %}">
613
614\end{verbatim}
615\end{frame}
616
617\subsection{Listar Registros}
618\begin{frame}[fragile]
619\begin{verbatim}
620Creamos el archivo ajax.py
621
622# -*- encoding: utf-8 -*-
623from django.conf import settings
624from django_datatables_view.base_datatable_view import (
625   BaseDatatableView)
626   
627from django.contrib.auth.models import (
628    User)
629
630class ListUsersAjaxView(BaseDatatableView):
631    model = User
632    columns = ['pk','first_name','last_name','username','email',
633               'date_joined', 'last_joined' ]
634    order_columns = ['pk', 'username']
635    max_display_length = 500
636   
637    def __init__(self):
638        super(ListUsersAjaxView, self).__init__()
639
640    def get_initial_queryset(self):
641        return self.model.objects.all()
642\end{verbatim}
643\end{frame}
644
645\begin{frame}[fragile]
646\begin{verbatim}
647def prepare_results(self, qs):
648  json_data = []
649  for item in qs:
650    json_data.append([
651      username,
652     "{0} {1}".format(str(item.first_name),str(item.last_name)),
653      item.email,
654      item.date_joined.strftime("%Y-%m-%d %H:%M:%S"),
655      last_login               
656    ])
657           
658  return json_data
659# Fin del archivo ajax.py
660
661#En el archivo urls.py anexar las siguientes lineas
662from .ajax import *
663
664urlpatterns = [
665    ....
666url(r'^listar-users/$', ListUsersAjaxView.as_view(),
667        name="listar_users"),
668\end{verbatim}
669\end{frame}
670
671\begin{frame}[fragile]
672\begin{verbatim}
673Se anexa el siguiente código el archivo index.html
674En la parte visual:
675
676<div id="datatable"></div>
677
678Y en la parte de código javascript
679
680<script type="text/javascript">
681$(document).ready(function() {
682   $('#datatable').dataTable({
683        "processing": true,
684        "serverSide": true,
685        "ajax": {% url 'listar_user'%},
686        language: {url: JSON_DATA}
687        });
688    $('#datatable')
689        .removeClass('display')
690        .addClass('table table-striped table-bordered');
691});
692</script>
693\end{verbatim}
694\end{frame}
695
696\subsection{Anexar registros}
697\begin{frame}[fragile]
698\begin{verbatim}
699Creamos el método en el archivo views.py
700
701def AnexarRegistro(request):
702    if request.method == 'POST':
703       
704        vusername = request.POST['username']
705        u = User(username = vusername)
706        u.save()
707        message = _("El usuario fue creado")
708        template = loader.get_template('personal/profile.html')
709    context = {'message':message}
710    return HttpResponse(template.render(context, request))
711       
712\end{verbatim}
713\end{frame}
714
715\subsection{Modificar y eliminar registros}
716\begin{frame}[fragile]
717\begin{verbatim}
718@login_required
719def change_profile(request):
720    """ Cambiar perfil de usuario
721    """
722    if request.method == 'POST':
723        user_id = request.POST['user_id']
724        personal = User.objects.get(user_id=request.user.id)               
725        personal.first_name = request.POST['fname']
726        personal.last_name = request.POST['lname']
727        personal.email = request.POST['email']
728        personal.is_active = request.POST.get('is_active')
729        personal.user.save()
730       
731        message = _("The profile change was made")
732        context = {'personal':personal,'message':message,}
733    template = loader.get_template('personal/profile.html')
734    return HttpResponse(template.render(context, request))
735<<<<<<< HEAD
736=======
737
738\end{verbatim}
739\end{frame}
740>>>>>>> f837b9d91ddf1c492cd58e875f097fb99eb9339c
741
742\begin{frame}[fragile]
743\begin{verbatim}
744@login_required
745def delete_personal(request):
746    """ Delete users
747    """
748    id = json.loads(request.POST['seleccionados'])
749    print id
750 
751    for id_values in id:
752        if id_values["id"] != "0":
753                   
754            u = User.objects.get(pk=int(id_values["id"]))
755            u.delete()   
756           
757    return redirect('personal')
758\end{verbatim}
759\end{frame}
760
761\begin{frame}[fragile]
762\begin{verbatim}
763@login_required
764def delete_personal(request):
765    """ Delete users
766    """
767    id = json.loads(request.POST['seleccionados'])
768    print id
769 
770    for id_values in id:
771        if id_values["id"] != "0":
772                   
773            u = User.objects.get(pk=int(id_values["id"]))
774            u.delete()   
775           
776    return redirect('personal')
777\end{verbatim}
778\end{frame}
779
780\subsection{View's}
781\begin{frame}[fragile]
782\begin{verbatim}
783####  ListView
784
785# En el archivo views.py
786
787from django.views.generic.list import ListView
788from django.utils import timezone
789
790from articles.models import Article
791
792class ArticleListView(ListView):
793
794    model = Article
795
796    def get_context_data(self, **kwargs):
797        context = super(ArticleListView,
798                        self).get_context_data(**kwargs)
799        context['now'] = timezone.now()
800        return context
801
802\end{verbatim}
803\end{frame}
804
805\begin{frame}[fragile]
806\begin{verbatim}
807
808# En el archivo urls.py
809from django.conf.urls import url
810
811from article.views import ArticleListView
812
813urlpatterns = [
814 url(r'^$',ArticleListView.as_view(),name='article-list'),
815]
816
817# El template
818<h1>Articles</h1>
819<ul>
820{% for article in object_list %}
821    <li>
822    {{ article.pub_date|date }} - {{ article.headline }}
823    </li>
824{% empty %}
825    <li>No articles yet.</li>
826{% endfor %}
827</ul>
828\end{verbatim}
829\end{frame}
830
831\begin{frame}[fragile]
832\begin{verbatim}
833#### DetailView
834
835# En el archivo views.py
836
837from django.views.generic.detail import DetailView
838from django.utils import timezone
839
840from articles.models import Article
841
842class ArticleDetailView(DetailView):
843
844    model = Article
845
846    def get_context_data(self, **kwargs):
847        context = super(ArticleDetailView, self).
848                  get_context_data(**kwargs)
849        context['now'] = timezone.now()
850        return context
851       
852\end{verbatim}
853\end{frame}
854
855\begin{frame}[fragile]
856\begin{verbatim}
857
858# En el archivo urls.py
859
860from django.conf.urls import url
861
862from article.views import ArticleDetailView
863
864urlpatterns = [
865 url(r'^(?P<slug>[-\w]+)/$',ArticleDetailView.as_view(),
866                            name='article-detail'),
867]
868
869# El template
870
871<h1>{{ object.headline }}</h1>
872<p>{{ object.content }}</p>
873<p>Reporter: {{ object.reporter }}</p>
874<p>Published: {{ object.pub_date|date }}</p>
875<p>Date: {{ now|date }}</p>
876\end{verbatim}
877\end{frame}
878
879\begin{frame}[fragile]
880\begin{verbatim}
881#### CreateView
882
883from django.views.generic.edit import CreateView
884from myapp.models import Author
885
886class AuthorCreate(CreateView):
887    model = Author
888    fields = ['name']
889
890# En el template
891
892<form action="" method="post">{% csrf_token %}
893    {{ form.as_p }}
894    <input type="submit" value="Save" />
895</form>
896
897\end{verbatim}
898\end{frame}
899
900\begin{frame}[fragile]
901\begin{verbatim}
902#### UpdateView
903
904from django.views.generic.edit import UpdateView
905from myapp.models import Author
906
907class AuthorUpdate(UpdateView):
908    model = Author
909    fields = ['name']
910    template_name_suffix = '_update_form'
911   
912# En el template
913
914<form action="" method="post">{% csrf_token %}
915    {{ form.as_p }}
916    <input type="submit" value="Update" />
917</form>
918
919\end{verbatim}
920\end{frame}
921
922\begin{frame}[fragile]
923\begin{verbatim}
924#### DeleteView
925
926from django.views.generic.edit import DeleteView
927from django.urls import reverse_lazy
928from myapp.models import Author
929
930class AuthorDelete(DeleteView):
931    model = Author
932    success_url = reverse_lazy('author-list')
933   
934# En el template
935
936<form action="" method="post">{% csrf_token %}
937    <p>Are you sure you want to delete "{{ object }}"?</p>
938    <input type="submit" value="Confirm" />
939</form>
940
941\end{verbatim}
942\end{frame}
943
944\subsection{Crear Login}
945\begin{frame}[fragile]
946\begin{verbatim}
947Creamos la aplicacion user desde la consola:
948
949python manage.py startapp user
950
951Editamos el archivo user/views.py:
952
953# -*- coding: utf-8 -*-
954<<<<<<< HEAD
955
956from django.shortcuts import render
957from django.contrib import messages
958from django.contrib.auth import (
959    authenticate, logout, login
960)
961from django.contrib.auth.models import (
962    Group, Permission, User
963)
964
965=======
966
967from django.shortcuts import render
968from django.contrib import messages
969from django.contrib.auth import (
970    authenticate, logout, login
971)
972from django.contrib.auth.models import (
973    Group, Permission, User
974)
975
976>>>>>>> f837b9d91ddf1c492cd58e875f097fb99eb9339c
977class LoginView(FormView):
978    form_class = FormularioLogin
979    template_name = 'users.login.html'
980    success_url = '/inicio/'
981\end{verbatim}
982\end{frame}
983
984\begin{frame}[fragile]
985\begin{verbatim}
986def form_valid(self, form):
987       
988    usuario = form.cleaned_data['usuario']
989    contrasena = form.cleaned_data['contrasena']
990    usuario = authenticate(username=usuario,password=contrasena)
991       
992    if usuario is not None:
993        login(self.request, usuario)
994        messages.info(self.request,'Bienvenido %s has ingresado\
995                                    Sistema con el usuario %s \
996                                    ' % (usuario.first_name,
997                                         usuario.username))
998    else:
999        self.success_url = reverse_lazy('users:login')
1000        messages.warning(self.request,'Verifique su nombre y \
1001                                       contraseña\
1002                                      y vuelve a intertar')
1003
1004    return super(LoginView, self).form_valid(form)
1005 
1006\end{verbatim}
1007\end{frame}
1008
1009\subsection{Registro de Usuarios}
1010\begin{frame}[fragile]
1011\begin{verbatim}
1012#### Crear Permisos desde el shell ejecutar
1013
1014from myapp.models import BlogPost
1015from django.contrib.auth.models import Permission
1016from django.contrib.contenttypes.models import ContentType
1017
1018content_type = ContentType.objects.get_for_model(BlogPost)
1019permission = Permission.objects.create(
1020    codename='can_publish',
1021    name='Can Publish Posts',
1022    content_type=content_type,
1023)
1024
1025\end{verbatim}
1026\end{frame}
1027
1028\begin{frame}[fragile]
1029\begin{verbatim}
1030
1031from django.contrib.auth.models import Permission, User
1032from django.contrib.contenttypes.models import ContentType
1033from django.shortcuts import get_object_or_404
1034
1035from myapp.models import BlogPost
1036
1037def user_gains_perms(request, user_id):
1038    user = get_object_or_404(User, pk=user_id)
1039    # any permission check will
1040    #cache the current set of permissions
1041    user.has_perm('myapp.change_blogpost')
1042
1043    content_type=ContentType.objects.get_for_model(BlogPost)
1044    permission = Permission.objects.get(
1045        codename='change_blogpost',
1046        content_type=content_type,
1047    )
1048    user.user_permissions.add(permission)
1049
1050\end{verbatim}
1051\end{frame}
1052
1053\subsection{Login required}
1054\begin{frame}[fragile]
1055\begin{verbatim}
1056
1057from django.contrib.auth.decorators import
1058  login_required, permission_required
1059from django.views.generic import TemplateView
1060
1061from .views import VoteView
1062
1063urlpatterns = [
1064    url(r'^about/$', login_required(
1065           TemplateView.as_view(template_name="secret.html"))),
1066    url(r'^vote/$', permission_required(
1067           'polls.can_vote')(VoteView.as_view())),
1068]
1069
1070\end{verbatim}
1071\end{frame}
1072
1073\subsection{Recuperar contraseña por correo}
1074\begin{frame}[fragile]
1075\begin{verbatim}
1076def newpassword(request):
1077    puser = request.POST['puser']
1078    try:
1079        user = User.objects.get(username=puser)
1080        randompass = ''.join([choice(
1081        '1234567890qwertyuiopasdfghjklzxcvbnm')
1082        for i in range(10)])
1083        print randompass
1084        subject = _('System: New Password')
1085        message = _('Your password is reset, new password: ')
1086                    + randompass
1087        user.email_user("subject","message")
1088        user.set_password(randompass)
1089        user.save()
1090    except:
1091        print "error send mail"
1092        mensaje = _("User not found")
1093    return redirect('/authenticate/signin')
1094 
1095\end{verbatim}
1096\end{frame}
1097
1098\subsection{Conceptos avanzados}
1099\begin{frame}[fragile]
1100\begin{verbatim}
1101Otros conceptos
1102
1103* Internacionalización
1104* Zonas Horarias
1105* Servidor Web
1106* Geodjango
1107* Django Rest
1108
1109 Entre otros...
1110<<<<<<< HEAD
1111=======
1112
1113\end{verbatim}
1114\end{frame}
1115
1116\subsection{Geodjango}
1117\begin{frame}[fragile]
1118\begin{verbatim}
1119Para la gestión de datos geolocalizados debe utilizar
1120una extensión de django denominada Geodjango
1121
1122Instalación de componentes para la gestión de mapas
1123en particular la extensión django.contrib.gis
1124
1125Entrar como root para la instalacion
1126
1127aptitude install python3.4 python3-pip python3.4-dev
1128python3-setuptools
1129
1130aptitude install python3-virtualenv virtualenvwrapper
1131
1132Salir del modo root y crear el ambiente:
1133
1134$ mkvirtualenv --python=/usr/bin/python3 geodjango
1135\end{verbatim}
1136\end{frame}
1137
1138\begin{frame}[fragile]
1139\begin{verbatim}
1140Instalar los requerimientos del proyecto
1141
1142Para activar el ambiente virtual geodjango ejecute el comando:
1143
1144$ workon geodjango
1145
1146Quedando activado el entorno virtual de esta manera.
1147
1148(geodjango)$
1149
1150Crear el archivo requerimientos.txt
1151vim requerimientos.txt
1152
1153*** Inicio del archivo requerimientos.txt
1154Django==1.11.4
1155psycopg2==2.7.1
1156pytz==2017.2
1157*** fin del archivo requeimientos.txt
1158
1159Ejecutar el comando de descarga e instalación
1160pip install -r requeimientos.txt
1161\end{verbatim}
1162\end{frame}
1163
1164\begin{frame}[fragile]
1165\begin{verbatim}
1166Crear el proyecto geodjango-demo
1167
1168django-admin startproject geodjango-demo
1169
1170cd geodjango-demo
1171
1172Crear base de datos y Migrar los modelos
1173>>>>>>> f837b9d91ddf1c492cd58e875f097fb99eb9339c
1174
1175Como super usuario instalar postgis:
1176
1177aptitude install postgis
1178
1179aptitude install postgresql-x.x-postgis-x.x
1180
1181Nota: las x.x debe ser sustituidad por la versión de
1182Postgres instalada
1183\end{verbatim}
1184\end{frame}
1185
1186<<<<<<< HEAD
1187=======
1188\begin{frame}[fragile]
1189\begin{verbatim}
1190Ingresar a la consola de postgres con la siguiente orden:
1191$ psql
1192
1193Ejecutar la siguiente sentencia estando en la consola de
1194postgres:
1195
1196postgres=# CREATE DATABASE geodjango OWNER=postgres;
1197postgres=#  \q
1198
1199$ psql geodjango
1200
1201geodjango=# CREATE EXTENSION postgis;
1202geodjango=# \q
1203
1204Editar el archivo geodjango-demo/settings.py
1205
1206INSTALLED_APPS = [
1207    ...
1208    'django.contrib.gis',
1209]
1210\end{verbatim}
1211\end{frame}
1212
1213\begin{frame}[fragile]
1214\begin{verbatim}
1215Modificar la conexión para la base de datos:
1216
1217DATABASES = {
1218    'default': {
1219        'ENGINE': 'django.contrib.gis.db.backends.postgis',
1220        'NAME': 'geodjango',
1221        'USER': 'administrador',
1222        'PASSWORD': 'clave',
1223        'HOST': 'localhost',
1224        'PORT': '5432',
1225        'ATOMIC_REQUESTS': True,
1226        # Crea transacciones en cada peticion de la vista
1227    }
1228}
1229
1230Para migrar los modelos del proyecto se debe usar
1231el siguiente comando:
1232
1233(geodjango)$ python manage.py makemigrations
1234(geodjango)$ python manage.py migrate
1235(geodjango)$ python manage.py createsuperusuer
1236\end{verbatim}
1237\end{frame}
1238
1239\begin{frame}[fragile]
1240\begin{verbatim}
1241Creamos la aplicación geolocation
1242(geodjango)$ python manage.py startapp geolocation
1243
1244Creamos el archivos geolocation/urls.py
1245# -*- coding: utf-8 -*-
1246from django.conf.urls import url
1247from .views import *
1248urlpatterns = [
1249                url(r'^register-poly/',
1250                    RegisterPolyView.as_view(),
1251                    name="register_poly"),
1252                url(r'^list-zipcode/',
1253                    ListZipcodeView.as_view(),
1254                    name="list_zipcode"),
1255                url(r'^delete-zipcode/(?P<pk>\d+)/',
1256                    ZipcodeDeleteView.as_view(),
1257                    name="delete_zipcode"),
1258                url(r'update-zipcode/(?P<pk>\d+)/$',
1259                    ZipCodeUpdate.as_view(),
1260                    name='update_zipcode')
1261              ]
1262\end{verbatim}
1263\end{frame}
1264
1265\begin{frame}[fragile]
1266\begin{verbatim}
1267Modificar el archivo geolocation/views.py
1268
1269# -*- coding: utf-8 -*-
1270from django.contrib import messages
1271from django.contrib.messages.views import SuccessMessageMixin
1272from django.urls import reverse_lazy
1273from django.views.generic.edit import (
1274    FormView, DeleteView, UpdateView
1275    )
1276from django.views.generic import ListView
1277
1278from .forms import *
1279from .models import *
1280
1281\end{verbatim}
1282\end{frame}
1283
1284\begin{frame}[fragile]
1285\begin{verbatim}
1286class RegisterPolyView(FormView):
1287    form_class = ZipcodeForms
1288    template_name = 'geodjango-template.html'
1289    success_url = '/geolocation/register-poly/'
1290    def form_valid(self, form, **kwargs):
1291        new_zipcode = form.save()
1292        messages.success(self.request,
1293        "ZipCode %s, registrado con exito" % (str(new_zipcode)))
1294        return super(RegisterPolyView, self).form_valid(form)
1295class ListZipcodeView(ListView):
1296    model = Zipcode
1297    template_name = 'geodjango-list.html'
1298    paginate_by = 3
1299class ZipcodeDeleteView(DeleteView):
1300    model = Zipcode
1301    success_url = reverse_lazy('geolocation:list_zipcode')
1302class ZipCodeUpdate(UpdateView, SuccessMessageMixin):
1303    model = Zipcode
1304    form_class = ZipcodeForms
1305    success_message = 'ZipCode Actualizado con exito'
1306    success_url = reverse_lazy('geolocation:list_zipcode')
1307\end{verbatim}
1308\end{frame}
1309
1310\begin{frame}[fragile]
1311\begin{verbatim}
1312Editar el archivo admin.py
1313# -*- coding: utf-8 -*-
1314from django.contrib.gis import admin
1315from .models import *
1316admin.site.register(Zipcode, admin.OSMGeoAdmin)
1317
1318Editar el archivo apps.py
1319from django.apps import AppConfig
1320class GeolocationConfig(AppConfig):
1321    name = 'geolocation'
1322
1323Editar el archivo forms.py
1324# -*- coding: utf-8 -*-
1325from django.contrib.gis import forms
1326from .models import *
1327
1328class ZipcodeForms(forms.ModelForm):
1329    class Meta:
1330        model = Zipcode
1331        fields = '__all__'
1332\end{verbatim}
1333\end{frame}
1334
1335\begin{frame}[fragile]
1336\begin{verbatim}
1337    def __init__(self, *args, **kwargs):
1338        super(ZipcodeForms, self).__init__(*args, **kwargs)
1339        self.fields['code'].widget.attrs.update(
1340           {'class': 'form-control','placeholder': 'Zip Code'})
1341        self.fields['code'].label = 'Zip Code'
1342        self.fields['code'].required = True
1343
1344        # Se le agrega la ruta donde se construye el mapa
1345        # con el default_zoom
1346        self.fields['poly'].widget =
1347         forms.OSMWidget.template_name = 'openlayers-cust.html'
1348
1349        # Se le agrega al campo los atributos que por defecto
1350        # tiene la ubicacion (lat lon) de Venezuela
1351        # Con un zoom por defecto de 5.2 y
1352        # Un alto y ancho de 600X400
1353        self.fields['poly'].widget = forms.OSMWidget(attrs={
1354                         'default_zoom': 5.2, 'map_width': 600,
1355                         'map_height': 400, 'default_lat': 8,
1356                         'default_lon': -66})
1357        self.fields['poly'].label = 'Cordenadas Poligonales'
1358        self.fields['poly'].required = True
1359\end{verbatim}
1360\end{frame}
1361
1362\begin{frame}[fragile]
1363\begin{verbatim}
1364Editar el archivo models.py
1365# -*- coding: utf-8 -*-
1366from django.contrib.gis.db import models
1367
1368class Zipcode(models.Model):
1369    code = models.CharField(max_length=5) #Campo del ZipCode
1370    poly = models.PolygonField() #Campo de la poligonal
1371    class Meta:
1372        ordering = ('code',)
1373        verbose_name = 'Zipcode'
1374        verbose_name_plural = 'Zipcodes'
1375    def __str__(self):
1376        return self.code
1377class Elevation(models.Model):
1378    name = models.CharField(max_length=100)
1379    rast = models.RasterField()
1380    class Meta:
1381        ordering = ('name',)
1382        verbose_name = 'Elevation'
1383        verbose_name_plural = 'Elevations'
1384    def __str__(self):
1385        return self.name
1386\end{verbatim}
1387\end{frame}
1388
1389\begin{frame}[fragile]
1390\begin{verbatim}
1391Editar el archivo geodjango-demo/settings.py
1392
1393INSTALLED_APPS = [
1394    ...
1395    'django.contrib.gis',
1396    'geolocation',
1397]
1398
1399Guardamos y ejecutamos el comando
1400(geodjango)$ python manage.py makemigrations geolocation
1401(geodjango)$ python manage.py migrate geolocation
1402
1403Editamos el Templates para lo cual creamos la carpeta templates
1404y creamos los archivos geodjango-template.html y
1405geodjango-list.html
1406
1407mkdir geolocation/templates
1408cd geolocation/templates
1409
1410\end{verbatim}
1411\end{frame}
1412
1413\begin{frame}[fragile]
1414\begin{verbatim}
1415Archivo geodjango-list.html
1416{% extends "admin/base.html" %}
1417{% block title %}Listar Zipcode {% endblock title %}
1418{% block branding %}
1419    <h1 id="site-name"><a href="{% url 'admin:index' %}">
1420    Demo-GeoDjango</a></h1>
1421{% endblock %}
1422{% block breadcrumbs %}
1423    <div class="breadcrumbs">
1424    <a href="{% url 'geolocation:register_poly' %}">
1425    Registrar ZipCode</a>/
1426    <a href="{% url 'geolocation:list_zipcode' %}">
1427    Listar ZipCode</a>
1428    {% if title %} &rsaquo; {{ title }}{% endif %}
1429    </div>
1430{% endblock breadcrumbs%}
1431{% block content %}
1432    <h1>Zip Codes</h1>
1433    <table><thead><tr><th>ZipCodes</th>
1434                      <th>Coordenadas</th>
1435                      <th>Acciones</th></tr></thead>
1436\end{verbatim}
1437\end{frame}
1438
1439\begin{frame}[fragile]
1440\begin{verbatim}
1441    {% for zips in object_list %}
1442        <tbody><tr>
1443         <td>{{ zips.code }}</td>
1444         <td>{{ zips.poly }}</td>
1445         <td><a title="Editar" class="changelink"
1446          href="{% url 'geolocation:update_zipcode' zips.pk %}">
1447          </a>
1448         <a title="Eliminar" class="deletelink"
1449          href="{% url 'geolocation:delete_zipcode' zips.pk %}">
1450          </a>
1451         </td></tr></tbody>
1452    {% empty %}
1453        <tbody>
1454            <tr><td>No hay zipcode.</td></tr>
1455        </tbody>
1456    {% endfor %}
1457 
1458    </table>
1459\end{verbatim}
1460\end{frame}
1461
1462\begin{frame}[fragile]
1463\begin{verbatim}
1464
1465    {% if is_paginated %}
1466        <div class="pagination">
1467            <span class="page-links">
1468                {% if page_obj.has_previous %}
1469<a href="/geolocation/list-zipcode/?page=
1470{{ page_obj.previous_page_number }}">Anterior</a>
1471                {% endif %}
1472                <span class="page-current">
1473Página {{ page_obj.number }}de{{ page_obj.paginator.num_pages }}
1474                </span>
1475                {% if page_obj.has_next %}
1476<a href="/geolocation/list-zipcode/?page=
1477{{ page_obj.next_page_number }}">Siguiente</a>
1478                {% endif %}
1479          </span>
1480        </div>
1481    {% endif %}
1482{% endblock content %}
1483""" Fin del archivo geodjango-list.html
1484\end{verbatim}
1485\end{frame}
1486
1487\begin{frame}[fragile]
1488\begin{verbatim}
1489""" Archivo geodjango-templates.html
1490{% extends "admin/base.html" %}
1491{% block title %}Registrar Zipcode {% endblock title %}
1492{% block extrastyle %}{{ form.media }}{% endblock extrastyle %}
1493{% block branding %}  <h1 id="site-name">
1494<a href="{% url 'admin:index' %}">Demo-GeoDjango</a></h1>
1495{% endblock branding %}
1496{% block breadcrumbs %}
1497    <div class="breadcrumbs">
1498    <a href="{% url 'geolocation:register_poly' %}">
1499    Registrar ZipCode</a>
1500    <a href="{% url 'geolocation:list_zipcode' %}">
1501    Listar ZipCode</a>
1502    {% if title %} &rsaquo; {{ title }}{% endif %} </div>
1503{% endblock breadcrumbs%}
1504{% block content %}
1505    <form method="post">{% csrf_token %}
1506        <div class="form-row">{{ form.as_p }}</div>
1507        <div class="submit-row">
1508         <input type="submit" value="Agregar ZipCode" />
1509        </div></form>
1510{% endblock content %}
1511\end{verbatim}
1512\end{frame}
1513
1514\begin{frame}[fragile]
1515\begin{verbatim}
1516""" Archivo openlayers-cust.html
1517
1518{% extends "gis/openlayers.html" %}
1519{% load l10n %}
1520
1521{% block options %}{{ block.super }}
1522options['default_lon'] = {{ default_lon|unlocalize }};
1523options['default_lat'] = {{ default_lat|unlocalize }};
1524options['default_zoom'] = {{ default_zoom|unlocalize }};
1525{% endblock %}
1526
1527{% block base_layer %}
1528var base_layer = new ol.layer.Tile({source:
1529                                    new ol.source.OSM()});
1530{% endblock %}
1531
1532\end{verbatim}
1533\end{frame}
1534
1535\begin{frame}[fragile]
1536\begin{verbatim}
1537
1538{% block content %}
1539    <form method="post">
1540    {% csrf_token %}
1541        <div class="form-row">
1542            {{ form.as_p }}
1543        </div>
1544        <div class="submit-row">
1545<label>&nbsp;</label>
1546<input type="submit" value="Agregar ZipCode" />
1547        </div>
1548    </form>
1549{% endblock content %}
1550
1551""" Fin del archivo geodjango-templates.html
1552
1553\end{verbatim}
1554\end{frame}
1555
1556\begin{frame}[fragile]
1557\begin{verbatim}
1558Editar el archivo geodjango-demo/urls.py
1559
1560from django.conf.urls import url, include
1561from django.contrib.gis import admin
1562
1563urlpatterns = [
1564    url(r'^admin/', admin.site.urls),
1565    url(r'^geolocation/', include('geolocation.urls',
1566    namespace="geolocation")),
1567]
1568
1569Guardar y ahora se puede ejecutar el comando
1570
1571(geodjango)$ python manage.py runserver
1572
1573Y acceder desde un navegador la dirección
1574
1575http://localhost:8000/geolocation/register-poly/
1576\end{verbatim}
1577\end{frame}
1578
1579
1580>>>>>>> f837b9d91ddf1c492cd58e875f097fb99eb9339c
1581\begin{frame}[plain]
1582
1583 
1584      \begin{center}
1585
1586        \font\endfont = cmss10 at 15.40mm
1587        \color{Brown}
1588        \endfont 
1589        \baselineskip 20.0mm
1590
1591        CENDITEL
1592
1593      \end{center}   
1594
1595   
1596\end{frame}
1597
1598
1599\end{document}
1600=======
16012       \usetheme{Berkeley}
16023       \usepackage[spanish]{babel}
16034       \usepackage[utf8]{inputenc}
16045       \usepackage[T1]{fontenc}
16056       \usepackage{lmodern}
16067       \usepackage{fancyhdr}
16078       \usepackage{graphicx}
16089       \usepackage{mathrsfs}
160910      \usepackage{amsmath}
161011      \usepackage{lmodern}
161112      \usepackage{multimedia}
161213      \usepackage{hyperref}
161314      \usepackage{varioref}
161415      \usepackage{ragged2e}
161516      \usepackage{etoolbox}
161617      \usepackage{lipsum}
161718      \usepackage{fancyvrb}
161819      \fvset{fontsize=\footnotesize}
161920      \RecustomVerbatimEnvironment{verbatim}{Verbatim}{}
162021      \apptocmd{\frame}{}{\justifying}{} % Allow optional arguments after frame.
162122      \usecolortheme[{rgb={0.6,0,0}}]{structure}
162223      \setbeamercovered{transparent}
162324      \setbeamertemplate{items}[ball]
162425      \setbeamertemplate{blocks}[rounded][shadow=true]
162526      \beamertemplateshadingbackground{gray!50}{white!50}
162627      \newtheorem{Ejemplo}{Django}
162728      \useoutertheme{infolines}
162829      \title []{Framework Django 1.11}
162930      \author{Instructor Ing. Erwin Paredes}
163031      %\logo{ \includegraphics[height=3cm]{figura/logo-blanco2.png}}
163132      \institute{CENDITEL}
163233      \date{\today}
163334     
163435      \begin{document}
163536     
163637      \section{Cenditel}
163738      \begin{frame}
163839      \maketitle
163940      \end{frame}
164041     
164142      \subsection{La Fundación}
164243      \begin{frame}
164344      \begin{block}{Fundación CENDITEL}
164445      \indent   
164546      Somos el Centro Nacional de Desarrollo e Investigación en Tecnologías Libres, cuyas actividades son el desarrollo de proyectos con impacto tecnológico enmarcados en las áreas de Software, Hardware y Telecomunicaciones.
164647      https://www.cenditel.gob.ve
164748     
164849      \end{block}
164950      \end{frame}
165051     
165152      \subsection{Finalidad del Curso}
165253      \begin{frame}
165354      \begin{block}{Finalidad}
165455           
165556      Consolidar la comunidad de desarrollo en software libre alrededor de la tecnología, en este caso el framework de desarrollo Django del lenguaje de programación Python
165657      \end{block}
165758      \end{frame}
165859     
165960      \subsection{Contenido del Curso}
166061      \begin{frame}
166162      \begin{block}{Contenido del Curso}
166263      \begin{itemize}
166364      \item 
166465      Introducción
166566      \item 
166667      Configurar ambiente de trabajo
166768      \item 
166869      Crear proyecto
166970      \item 
167071      Crear aplicaciones y estructura del proyecto
167172      \item 
167273      Modelos y migraciones
167374      \item 
167475      Relaciones
167576      \item 
167677      Django shell y Querysets
167778      \item 
167879      Configurar URLs y primera views
167980      \item 
168081      Sistema de plantillas
168182      \item 
168283      Configurar archivos estáticos
168384      \item 
168485      Listar Registros
168586      \item 
168687      Formularios y vista para anexar registros
168788      \item 
168889      Vistas para modificar y eliminar registros
168990      \end{itemize}
169091      \end{block}
169192      \end{frame}
169293     
169394     
169495      \begin{frame}
169596      \begin{block}{Contenido del Curso}
169697      \begin{itemize}
169798      \item
169899      ListView, CreateView, UpdateView, DeleteView   
1699100     \item
1700101     Crear Login
1701102     \item
1702103     Registro de Usuarios
1703104     \item
1704105     Decorador Login required
1705106     \item
1706107     Recuperar contraseña por correo
1707108     \item
1708109     Introducción a conceptos avanzados
1709110     \end{itemize}
1710111     \end{block}
1711112     \end{frame}
1712113     
1713114     
1714115     
1715116     \section{Django}
1716117     \subsection{Introducción}
1717118     \begin{frame}
1718119     Django: Es un entorno de trabajo para el desarrollo Web, basado en el lenguaje de programación Python.
1719120     
1720121     Un entorno de trabajo o framework, implica una estructura conceptual y conjunto de herramientas que típicamente son un conjunto de librerías, que permite organizar el desarrollo.
1721122     
1722123     Para el framework Django la estructura conceptual es el denominado MVC (Modelo Vista Controlador), esto es, se organiza el desarrollo en módulos que separan el modelo de datos, la interfaz o vista y el comportamiento.
1723124     
1724125     Por lo que para cada aplicación o módulo que conforma el proyecto se agrupa en lo siguientes archivos:
1725126     
1726127     \begin{itemize}
1727128      \item models.py :Contiene las clases que definen la estructura de datos
1728129      \item views.py  :Contiene la codificación de las funcionalidades que permiten controlar el comportamiento del sistema.
1729130      \item *.html    :Contiene la codificación de la interfaz
1730131     \end{itemize}
1731132     \end{frame}
1732133     
1733134     \subsection{Configurar ambiente de trabajo}
1734135     \begin{frame}[fragile]
1735136     
1736137     \begin{Large}\textbf{Sitio Oficial}\end{Large}
1737138     \begin{verbatim}
1738139     
1739140     https://www.djangoproject.com/
1740141     
1741142     Instalación
1742143     
1743144     https://docs.djangoproject.com/en/1.11/intro/install
1744145     
1745146     Descarga:
1746147     
1747148     https://www.djangoproject.com/download/
1748149     \end{verbatim}
1749150     \end{frame}
1750151     
1751152     \begin{frame}[fragile]
1752153     
1753154     \begin{Large}\textbf{Instalación}\end{Large}
1754155     \begin{verbatim}
1755156     // Descomprimir el archivo
1756157     
1757158     tar -xzvf Django1.11.tar.gz
1758159     
1759160     cd Django1.11
1760161     
1761162     python setup.py install
1762163     
1763164     // Comprobar la instalación del framework:
1764165     
1765166     python
1766167     import django
1767168     django.VERSION
1768169     
1769170     Ctrl + D
1770171     \end{verbatim}
1771172     \end{frame}
1772173     
1773174     \subsection{Crear proyecto}
1774175     \begin{frame}[fragile]
1775176     
1776177     \begin{verbatim}
1777178     // Crear el primer proyecto:
1778179     
1779180     django-admin startproject curso
1780181     
1781182     // este comando crea la siguiente infraestructura
1782183     de carpetas y archivos:
1783184     
1784185     curso/
1785186         manage.py
1786187         curso/
1787188             __init__.py
1788189             settings.py
1789190             urls.py
1790191             wsgi.py
1791192     
1792193     
1793194     Configurar la base de datos
1794195     
1795196     \end{verbatim}
1796197     \end{frame}
1797198     
1798199     \begin{frame}[fragile]
1799200     
1800201     \begin{verbatim}
1801202     // Se debe haber instalado el gestor de la Base de
1802203     Datos Postgresql  y la librería de conexión psycopg2
1803204     // Creamos la base de datos:
1804205     su postgres
1805206     psql
1806207     CREATE USER administrador;
1807208     CREATE DATABASE curso;
1808209     
1809210     // Se edita el archivo curso/settings.py la constante
1810211     DATABASES = {
1811212        'default': {
1812213             'ENGINE': 'django.db.backends.postgresql',
1813214             'NAME': 'curso',
1814215             'USER': 'administrador',
1815216             'PASSWORD': 'clave',
1816217             'HOST': '127.0.0.1',
1817218             'PORT': '5432',
1818219       } }
1819220     \end{verbatim}
1820221     \end{frame}
1821222     
1822223     \begin{frame}[fragile]
1823224     \begin{verbatim}
1824225     // Se guarda y ejecuta el siguiente comando para
1825226     crear las tablas iniciales del proyecto:
1826227     
1827228     python manage.py migrate
1828229     
1829230     // Se ejcuta el comando para crear el superusuario o
1830231     usuario administrador del proyecto:
1831232     
1832233     python manage.py createsuperuser
1833234     
1834235     // Se introducen los datos que solicita
1835236     // Se ejecuta el siguiente comando para activar el
1836237     servidor de prueba de forma local
1837238     
1838239     python manage.py runserver
1839240     \end{verbatim}
1840241     \end{frame}
1841242     
1842243     \begin{frame}[fragile]
1843244     \begin{verbatim}
1844245     python manage.py runserver
1845246     
1846247     // Arroja el siguiente mensaje
1847248     Performing system checks...
1848249     
1849250     System check identified no issues (0 silenced).
1850251     
1851252     July 26, 2017 - 15:32:30
1852253     Django version 1.11.3,using settings 'curso.settings'
1853254     Starting development server at http://127.0.0.1:8000/
1854255     Quit the server with CONTROL-C.
1855256     
1856257     // Abrimos el navegador de preferencia y colocamos la
1857258     siguiente dirección para acceder al sistema
1858259     administrativo del proyecto:
1859260     
1860261     http://localhost:8000/admin
1861262     \end{verbatim}
1862263     \end{frame}
1863264     
1864265     \subsection{Crear aplicaciones}
1865266     \begin{frame}[fragile]
1866267     \begin{verbatim}
1867268     
1868269     http://localhost:8000/admin
1869270     
1870271     // En el debemos autenticarnos con el usuario y
1871272     password del superusuario creado en los pasos
1872273     anteriores
1873274     
1874275     // Allí podemos gestionar los usuarios del sistema
1875276     así como los grupos que evenctualmente se utilizan
1876277     para asignar permisos de acceso.
1877278     
1878279     // En el terminal presionar las teclas Ctrl + C para
1879280     interrumpir la ejecución del servidor y así crear
1880281     las aplicaciones del proyecto.
1881282     
1882283     python manage.py startapp encuesta
1883284     
1884285     \end{verbatim}
1885286     \end{frame}
1886287     
1887288     \subsection{Modelos}
1888289     \begin{frame}[fragile]
1889290     \begin{verbatim}
1890291     python manage.py startapp encuesta
1891292     
1892293     // Se edita el archivo encuesta/models.py
1893294     
1894295     from django.db import models
1895296     
1896297     class Question(models.Model):
1897298         question_text = models.CharField(max_length=200)
1898299         pub_date =models.DateTimeField('date published')
1899300     
1900301     class Choice(models.Model):
1901302         question = models.ForeignKey(Question,
1902303                    on_delete=models.CASCADE)
1903304         choice_text = models.CharField(max_length=200)
1904305         votes = models.IntegerField(default=0)
1905306     
1906307     \end{verbatim}
1907308     \end{frame}
1908309     
1909310     \begin{frame}[fragile]
1910311     \begin{verbatim}
1911312     // Almacenamos y editamos el archivo
1912313     curso/settings.py la constante:
1913314     
1914315     INSTALLED_APPS = [
1915316         ...
1916317         'django.contrib.staticfiles',
1917318         'encuesta',
1918319     ]
1919320     
1920321     // Para crear las tablas correspondiente de models.py
1921322     se ejecuta el comando:
1922323     
1923324     python manage.py makemigrations encuesta
1924325     
1925326     python manage.py migrate encuesta
1926327     
1927328     \end{verbatim}
1928329     \end{frame}
1929330     
1930331     \subsection{Relaciones}
1931332     \begin{frame}[fragile]
1932333     \begin{verbatim}
1933334     // Para el manejo de las tablas por medio del
1934335     framework se puede realizar desde el terminal
1935336     con el comando:
1936337     
1937338     python manage.py shell
1938339     
1939340     
1940341     \end{verbatim}
1941342     \end{frame}
1942343     
1943344     \subsection{Django shell y Querysets}
1944345     \begin{frame}[fragile]
1945346     \begin{verbatim}
1946347     
1947348     // Allí podemos ejecutar las siguientes instrucciones
1948349     
1949350     from encuesta.models import Question, Choice
1950351     from django.utils import timezone
1951352     
1952353     Question.objects.all()
1953354     q = Question(question_text="Que hay de nuevo?",
1954355                          pub_date=timezone.now())
1955356     q.save()
1956357     q.id
1957358     q.question_text
1958359     q.pub_date
1959360     q.question_text = "Q ai d nuevo?"
1960361     q.save()
1961362     
1962363     Ctril + D para salir
1963364     \end{verbatim}
1964365     \end{frame}
1965366     
1966367     \begin{frame}[fragile]
1967368     \begin{verbatim}
1968369     Editamos nuevamente el archivo encuesta/models.py
1969370     para añadir el sigueinte metodo a la clase Question
1970371     
1971372     import datetime
1972373     
1973374     from django.db import models
1974375     from django.utils import timezone
1975376     
1976377     class Question(models.Model):
1977378         # ...
1978379         def was_published_recently(self):
1979380             return self.pub_date >= timezone.now() -
1980381                           datetime.timedelta(days=1)
1981382     
1982383     Guardamos y volvemos a terminal:
1983384     
1984385     python manage.py shell
1985386     
1986387     \end{verbatim}
1987388     \end{frame}
1988389     
1989390     \begin{frame}[fragile]
1990391     \begin{verbatim}
1991392     from polls.models import Question, Choice
1992393     
1993394     Question.objects.all()
1994395     q = Question.objects.get(pk=1)
1995396     q.was_published_recently()
1996397     
1997398     q = Question.objects.filter(id=1)
1998399     
1999400     q = Question.objects.filter(
2000401               question_text__startswith='Q')
2001402     
2002403     from django.utils import timezone
2003404     current_year = timezone.now().year
2004405     Question.objects.get(pub_date__year=current_year)
2005406     
2006407     Question.objects.get(id=2) Error...
2007408     \end{verbatim}
2008409     \end{frame}
2009410     
2010411     \begin{frame}[fragile]
2011412     \begin{verbatim}
2012413     q = Question.objects.get(pk=1)
2013414     q.choice_set.all()
2014415     q.choice_set.create(choice_text='No mucho', votes=0)
2015416     q.choice_set.create(choice_text='Muchas cosas'
2016417                                                ,votes=0)
2017418     c = q.choice_set.create(choice_text='De todo un poco'
2018419                                                ,votes=0)
2019420     
2020421     c.question
2021422     
2022423     q.choice_set.all()
2023424     q.choice_set.count()
2024425     
2025426     Crtl + D para salir
2026427     
2027428     \end{verbatim}
2028429     \end{frame}
2029430     
2030431     \begin{frame}[fragile]
2031432     \begin{verbatim}
2032433     Incluir el modelo de la aplicación encuesta
2033434     en el sistema admin:
2034435     
2035436     Editamos el archivo encuesta/admin.py
2036437     from django.contrib import admin
2037438     
2038439     from .models import Question
2039440     
2040441     admin.site.register(Question)
2041442     
2042443     Guardamos y ejecutamos el servidor
2043444     de prueba nuevamente:
2044445     
2045446     python manage.py runserver
2046447     
2047448     en el navegador http://localhost:8000/admin
2048449     
2049450     \end{verbatim}
2050451     \end{frame}
2051452     
2052453     \subsection{Configurar URLs y primera views}
2053454     \begin{frame}[fragile]
2054455     \begin{verbatim}
2055456     Crear la primera vista para acceso del proyecto
2056457     Editamos el archivo encuesta/urls.py
2057458     
2058459     from django.conf.urls import url
2059460     from . import views
2060461     urlpatterns = [
2061462         # ex: /encueta/
2062463         url(r'^$', views.index, name='index'),
2063464         # ex: /encuesta/5/
2064465         url(r'^(?P<question_id>[0-9]+)/$',
2065466         views.detail, name='detail'),
2066467         # ex: /encuesta/5/results/
2067468         url(r'^(?P<question_id>[0-9]+)/results/$',
2068469         views.results, name='results'),
2069470         # ex: /encuesta/5/vote/
2070471         url(r'^(?P<question_id>[0-9]+)/vote/$',
2071472          views.vote, name='vote'),
2072473     ]
2073474     \end{verbatim}
2074475     \end{frame}
2075476     
2076477     \begin{frame}[fragile]
2077478     \begin{verbatim}
2078479     Editamos el archivo encuesta/views.py:
2079480     
2080481     from django.http import HttpResponse
2081482     from .models import Question
2082483     
2083484     def index(request):
2084485         question_list = Question.objects.order_by('-pub_date')[:5]
2085486         output = ', '.join([q.question_text for q in question_list])
2086487         return HttpResponse(output)
2087488     
2088489     def detail(request, question_id):
2089490         return HttpResponse("Question No: %s." % question_id)
2090491     
2091492     def results(request, question_id):
2092493         response = "Results of question %s."
2093494         return HttpResponse(response % question_id)
2094495     
2095496     def vote(request, question_id):
2096497         return HttpResponse("Voting on question %s." % question_id)
2097498     \end{verbatim}
2098499     \end{frame}
2099500     
2100501     \begin{frame}[fragile]
2101502     \begin{verbatim}
2102503     Guardamos y ejecutamos el servidor de prueba y
2103504     probamos los enlaces desde el navegador:
2104505     
2105506     python manage.py runserver
2106507     
2107508     En el navegador probamos los siguientes enlaces:
2108509     
2109510     http://localhost:8000/encueta
2110511     http://localhost:8000/encueta/1
2111512     http://localhost:8000/encueta/1/result
2112513     http://localhost:8000/encueta/1/vote
2113514     
2114515     \end{verbatim}
2115516     \end{frame}
2116517     
2117518     \subsection{Sistema de plantillas}
2118519     
2119520     \begin{frame}[fragile]
2120521     \begin{verbatim}
2121522     Uso del plantillas:
2122523     
2123524     Creamos la siguiente estructura
2124525     
2125526     cd encuesta
2126527     mkdir templates
2127528     mkdir templates/encuesta
2128529     
2129530     y editamos el archivo index.html allí
2130531     
2131532     gedit encuesta/templates/encuesta/index.html
2132533     
2133534     \end{verbatim}
2134535     \end{frame}
2135536     
2136537     \begin{frame}[fragile]
2137538     \begin{verbatim}
2138539     {% if question_list %}
2139540         <ul>
2140541         {% for question in question_list %}
2141542             <li>
2142543              <a href="/encuesta/{{ question.id }}/">
2143544               {{
2144545                 question.question_text
2145546               }}
2146547              </a>
2147548             </li>
2148549         {% endfor %}
2149550         </ul>
2150551     {% else %}
2151552         <p>No hay encuestas.</p>
2152553     {% endif %}
2153554     \end{verbatim}
2154555     \end{frame}
2155556     
2156557     \begin{frame}[fragile]
2157558     \begin{verbatim}
2158559     Guardamos y modificamos el archivo encuesta views.py
2159560     para que utilice la plantilla
2160561     
2161562     from django.http import HttpResponse
2162563     from django.template import loader
2163564     
2164565     from .models import Question
2165566     
2166567     
2167568     def index(request):
2168569         question_list = Question.objects.order_by('-pub_date')[:5]
2169570         template = loader.get_template('polls/index.html')
2170571         context = {
2171572             'question_list': question_list,
2172573         }
2173574         return HttpResponse(template.render(context, request))
2174575     
2175576     \end{verbatim}
2176577     \end{frame}
2177578     
2178579     \begin{frame}[fragile]
2179580     \begin{verbatim}
2180581     o utilizando la shortcuts render
2181582     
2182583     from django.shortcuts import render
2183584     
2184585     from .models import Question
2185586     
2186587     
2187588     def index(request):
2188589         question_list = Question.objects.order_by('-pub_date')[:5]
2189590         context = {'question_list': question_list}
2190591         return render(request, 'polls/index.html', context)
2191592     
2192593     
2193594     \end{verbatim}
2194595     \end{frame}
2195596     
2196597     \subsection{Configurar estáticos}
2197598     \begin{frame}[fragile]
2198599     \begin{verbatim}
2199600     Descargar plantillas prediseñadas, por ejemplo:
2200601     
2201602     https://adminlte.io/
2202603     
2203604     Copiar los directorios ccs y js en los en la carpeta static
2204605     
2205606     Copiar los archivo *.html en la carpeta templates
2206607     
2207608     Editar index.html y cambiar los enlaces a cada archivo en:
2208609     
2209610     <link rel="stylesheet"
2210611     href="{% static 'css/DataTables/jquery.dataTables.min.css' %}">
2211612     
2212613     \end{verbatim}
2213614     \end{frame}
2214615     
2215616     \subsection{Listar Registros}
2216617     \begin{frame}[fragile]
2217618     \begin{verbatim}
2218619     Creamos el archivo ajax.py
2219620     
2220621     # -*- encoding: utf-8 -*-
2221622     from django.conf import settings
2222623     from django_datatables_view.base_datatable_view import (
2223624        BaseDatatableView)
2224625       
2225626     from django.contrib.auth.models import (
2226627         User)
2227628     
2228629     class ListUsersAjaxView(BaseDatatableView):
2229630         model = User
2230631         columns = ['pk','first_name','last_name','username','email',
2231632                    'date_joined', 'last_joined' ]
2232633         order_columns = ['pk', 'username']
2233634         max_display_length = 500
2234635       
2235636         def __init__(self):
2236637             super(ListUsersAjaxView, self).__init__()
2237638     
2238639         def get_initial_queryset(self):
2239640             return self.model.objects.all()
2240641     \end{verbatim}
2241642     \end{frame}
2242643     
2243644     \begin{frame}[fragile]
2244645     \begin{verbatim}
2245646     def prepare_results(self, qs):
2246647       json_data = []
2247648       for item in qs:
2248649         json_data.append([
2249650           username,
2250651          "{0} {1}".format(str(item.first_name),str(item.last_name)),
2251652           item.email,
2252653           item.date_joined.strftime("%Y-%m-%d %H:%M:%S"),
2253654           last_login               
2254655         ])
2255656               
2256657       return json_data
2257658     # Fin del archivo ajax.py
2258659     
2259660     #En el archivo urls.py anexar las siguientes lineas
2260661     from .ajax import *
2261662     
2262663     urlpatterns = [
2263664         ....
2264665     url(r'^listar-users/$', ListUsersAjaxView.as_view(),
2265666             name="listar_users"),
2266667     \end{verbatim}
2267668     \end{frame}
2268669     
2269670     \begin{frame}[fragile]
2270671     \begin{verbatim}
2271672     Se anexa el siguiente código el archivo index.html
2272673     En la parte visual:
2273674     
2274675     <div id="datatable"></div>
2275676     
2276677     Y en la parte de código javascript
2277678     
2278679     <script type="text/javascript">
2279680     $(document).ready(function() {
2280681        $('#datatable').dataTable({
2281682             "processing": true,
2282683             "serverSide": true,
2283684             "ajax": {% url 'listar_user'%},
2284685             language: {url: JSON_DATA}
2285686             });
2286687         $('#datatable')
2287688             .removeClass('display')
2288689             .addClass('table table-striped table-bordered');
2289690     });
2290691     </script>
2291692     \end{verbatim}
2292693     \end{frame}
2293694     
2294695     \subsection{Anexar registros}
2295696     \begin{frame}[fragile]
2296697     \begin{verbatim}
2297698     Creamos el método en el archivo views.py
2298699     
2299700     def AnexarRegistro(request):
2300701         if request.method == 'POST':
2301702           
2302703             vusername = request.POST['username']
2303704             u = User(username = vusername)
2304705             u.save()
2305706             message = _("El usuario fue creado")
2306707             template = loader.get_template('personal/profile.html')
2307708         context = {'message':message}
2308709         return HttpResponse(template.render(context, request))
2309710           
2310711     \end{verbatim}
2311712     \end{frame}
2312713     
2313714     \subsection{Modificar y eliminar registros}
2314715     \begin{frame}[fragile]
2315716     \begin{verbatim}
2316717     @login_required
2317718     def change_profile(request):
2318719         """ Cambiar perfil de usuario
2319720         """
2320721         if request.method == 'POST':
2321722             user_id = request.POST['user_id']
2322723             personal = User.objects.get(user_id=request.user.id)               
2323724             personal.first_name = request.POST['fname']
2324725             personal.last_name = request.POST['lname']
2325726             personal.email = request.POST['email']
2326727             personal.is_active = request.POST.get('is_active')
2327728             personal.user.save()
2328729           
2329730             message = _("The profile change was made")
2330731             context = {'personal':personal,'message':message,}
2331732         template = loader.get_template('personal/profile.html')
2332733         return HttpResponse(template.render(context, request))
2333734     
2334735     \end{verbatim}
2335736     \end{frame}
2336737     
2337738     \begin{frame}[fragile]
2338739     \begin{verbatim}
2339740     @login_required
2340741     def delete_personal(request):
2341742         """ Delete users
2342743         """
2343744         id = json.loads(request.POST['seleccionados'])
2344745         print id
2345746     
2346747         for id_values in id:
2347748             if id_values["id"] != "0":
2348749                       
2349750                 u = User.objects.get(pk=int(id_values["id"]))
2350751                 u.delete()   
2351752               
2352753         return redirect('personal')
2353754     \end{verbatim}
2354755     \end{frame}
2355756     
2356757     \subsection{View's}
2357758     \begin{frame}[fragile]
2358759     \begin{verbatim}
2359760     ####  ListView
2360761     
2361762     # En el archivo views.py
2362763     
2363764     from django.views.generic.list import ListView
2364765     from django.utils import timezone
2365766     
2366767     from articles.models import Article
2367768     
2368769     class ArticleListView(ListView):
2369770     
2370771         model = Article
2371772     
2372773         def get_context_data(self, **kwargs):
2373774             context = super(ArticleListView,
2374775                             self).get_context_data(**kwargs)
2375776             context['now'] = timezone.now()
2376777             return context
2377778     
2378779     \end{verbatim}
2379780     \end{frame}
2380781     
2381782     \begin{frame}[fragile]
2382783     \begin{verbatim}
2383784     
2384785     # En el archivo urls.py
2385786     from django.conf.urls import url
2386787     
2387788     from article.views import ArticleListView
2388789     
2389790     urlpatterns = [
2390791      url(r'^$',ArticleListView.as_view(),name='article-list'),
2391792     ]
2392793     
2393794     # El template
2394795     <h1>Articles</h1>
2395796     <ul>
2396797     {% for article in object_list %}
2397798         <li>
2398799         {{ article.pub_date|date }} - {{ article.headline }}
2399800         </li>
2400801     {% empty %}
2401802         <li>No articles yet.</li>
2402803     {% endfor %}
2403804     </ul>
2404805     \end{verbatim}
2405806     \end{frame}
2406807     
2407808     \begin{frame}[fragile]
2408809     \begin{verbatim}
2409810     #### DetailView
2410811     
2411812     # En el archivo views.py
2412813     
2413814     from django.views.generic.detail import DetailView
2414815     from django.utils import timezone
2415816     
2416817     from articles.models import Article
2417818     
2418819     class ArticleDetailView(DetailView):
2419820     
2420821         model = Article
2421822     
2422823         def get_context_data(self, **kwargs):
2423824             context = super(ArticleDetailView, self).
2424825                       get_context_data(**kwargs)
2425826             context['now'] = timezone.now()
2426827             return context
2427828           
2428829     \end{verbatim}
2429830     \end{frame}
2430831     
2431832     \begin{frame}[fragile]
2432833     \begin{verbatim}
2433834     
2434835     # En el archivo urls.py
2435836     
2436837     from django.conf.urls import url
2437838     
2438839     from article.views import ArticleDetailView
2439840     
2440841     urlpatterns = [
2441842      url(r'^(?P<slug>[-\w]+)/$',ArticleDetailView.as_view(),
2442843                                 name='article-detail'),
2443844     ]
2444845     
2445846     # El template
2446847     
2447848     <h1>{{ object.headline }}</h1>
2448849     <p>{{ object.content }}</p>
2449850     <p>Reporter: {{ object.reporter }}</p>
2450851     <p>Published: {{ object.pub_date|date }}</p>
2451852     <p>Date: {{ now|date }}</p>
2452853     \end{verbatim}
2453854     \end{frame}
2454855     
2455856     \begin{frame}[fragile]
2456857     \begin{verbatim}
2457858     #### CreateView
2458859     
2459860     from django.views.generic.edit import CreateView
2460861     from myapp.models import Author
2461862     
2462863     class AuthorCreate(CreateView):
2463864         model = Author
2464865         fields = ['name']
2465866     
2466867     # En el template
2467868     
2468869     <form action="" method="post">{% csrf_token %}
2469870         {{ form.as_p }}
2470871         <input type="submit" value="Save" />
2471872     </form>
2472873     
2473874     \end{verbatim}
2474875     \end{frame}
2475876     
2476877     \begin{frame}[fragile]
2477878     \begin{verbatim}
2478879     #### UpdateView
2479880     
2480881     from django.views.generic.edit import UpdateView
2481882     from myapp.models import Author
2482883     
2483884     class AuthorUpdate(UpdateView):
2484885         model = Author
2485886         fields = ['name']
2486887         template_name_suffix = '_update_form'
2487888       
2488889     # En el template
2489890     
2490891     <form action="" method="post">{% csrf_token %}
2491892         {{ form.as_p }}
2492893         <input type="submit" value="Update" />
2493894     </form>
2494895     
2495896     \end{verbatim}
2496897     \end{frame}
2497898     
2498899     \begin{frame}[fragile]
2499900     \begin{verbatim}
2500901     #### DeleteView
2501902     
2502903     from django.views.generic.edit import DeleteView
2503904     from django.urls import reverse_lazy
2504905     from myapp.models import Author
2505906     
2506907     class AuthorDelete(DeleteView):
2507908         model = Author
2508909         success_url = reverse_lazy('author-list')
2509910       
2510911     # En el template
2511912     
2512913     <form action="" method="post">{% csrf_token %}
2513914         <p>Are you sure you want to delete "{{ object }}"?</p>
2514915         <input type="submit" value="Confirm" />
2515916     </form>
2516917     
2517918     \end{verbatim}
2518919     \end{frame}
2519920     
2520921     \subsection{Crear Login}
2521922     \begin{frame}[fragile]
2522923     \begin{verbatim}
2523924     Creamos la aplicacion user desde la consola:
2524925     
2525926     python manage.py startapp user
2526927     
2527928     Editamos el archivo user/views.py:
2528929     
2529930     # -*- coding: utf-8 -*-
2530931     
2531932     from django.shortcuts import render
2532933     from django.contrib import messages
2533934     from django.contrib.auth import (
2534935         authenticate, logout, login
2535936     )
2536937     from django.contrib.auth.models import (
2537938         Group, Permission, User
2538939     )
2539940     
2540941     class LoginView(FormView):
2541942         form_class = FormularioLogin
2542943         template_name = 'users.login.html'
2543944         success_url = '/inicio/'
2544945     \end{verbatim}
2545946     \end{frame}
2546947     
2547948     \begin{frame}[fragile]
2548949     \begin{verbatim}
2549950     def form_valid(self, form):
2550951           
2551952         usuario = form.cleaned_data['usuario']
2552953         contrasena = form.cleaned_data['contrasena']
2553954         usuario = authenticate(username=usuario,password=contrasena)
2554955           
2555956         if usuario is not None:
2556957             login(self.request, usuario)
2557958             messages.info(self.request,'Bienvenido %s has ingresado\
2558959                                         Sistema con el usuario %s \
2559960                                         ' % (usuario.first_name,
2560961                                              usuario.username))
2561962         else:
2562963             self.success_url = reverse_lazy('users:login')
2563964             messages.warning(self.request,'Verifique su nombre y \
2564965                                            contraseña\
2565966                                           y vuelve a intertar')
2566967     
2567968         return super(LoginView, self).form_valid(form)
2568969     
2569970     \end{verbatim}
2570971     \end{frame}
2571972     
2572973     \subsection{Registro de Usuarios}
2573974     \begin{frame}[fragile]
2574975     \begin{verbatim}
2575976     #### Crear Permisos desde el shell ejecutar
2576977     
2577978     from myapp.models import BlogPost
2578979     from django.contrib.auth.models import Permission
2579980     from django.contrib.contenttypes.models import ContentType
2580981     
2581982     content_type = ContentType.objects.get_for_model(BlogPost)
2582983     permission = Permission.objects.create(
2583984         codename='can_publish',
2584985         name='Can Publish Posts',
2585986         content_type=content_type,
2586987     )
2587988     
2588989     \end{verbatim}
2589990     \end{frame}
2590991     
2591992     \begin{frame}[fragile]
2592993     \begin{verbatim}
2593994     
2594995     from django.contrib.auth.models import Permission, User
2595996     from django.contrib.contenttypes.models import ContentType
2596997     from django.shortcuts import get_object_or_404
2597998     
2598999     from myapp.models import BlogPost
25991000   
26001001    def user_gains_perms(request, user_id):
26011002        user = get_object_or_404(User, pk=user_id)
26021003        # any permission check will
26031004        #cache the current set of permissions
26041005        user.has_perm('myapp.change_blogpost')
26051006   
26061007        content_type=ContentType.objects.get_for_model(BlogPost)
26071008        permission = Permission.objects.get(
26081009            codename='change_blogpost',
26091010            content_type=content_type,
26101011        )
26111012        user.user_permissions.add(permission)
26121013   
26131014    \end{verbatim}
26141015    \end{frame}
26151016   
26161017    \subsection{Login required}
26171018    \begin{frame}[fragile]
26181019    \begin{verbatim}
26191020   
26201021    from django.contrib.auth.decorators import
26211022      login_required, permission_required
26221023    from django.views.generic import TemplateView
26231024   
26241025    from .views import VoteView
26251026   
26261027    urlpatterns = [
26271028        url(r'^about/$', login_required(
26281029               TemplateView.as_view(template_name="secret.html"))),
26291030        url(r'^vote/$', permission_required(
26301031               'polls.can_vote')(VoteView.as_view())),
26311032    ]
26321033   
26331034    \end{verbatim}
26341035    \end{frame}
26351036   
26361037    \subsection{Recuperar contraseña por correo}
26371038    \begin{frame}[fragile]
26381039    \begin{verbatim}
26391040    def newpassword(request):
26401041        puser = request.POST['puser']
26411042        try:
26421043            user = User.objects.get(username=puser)
26431044            randompass = ''.join([choice(
26441045            '1234567890qwertyuiopasdfghjklzxcvbnm')
26451046            for i in range(10)])
26461047            print randompass
26471048            subject = _('System: New Password')
26481049            message = _('Your password is reset, new password: ')
26491050                        + randompass
26501051            user.email_user("subject","message")
26511052            user.set_password(randompass)
26521053            user.save()
26531054        except:
26541055            print "error send mail"
26551056            mensaje = _("User not found")
26561057        return redirect('/authenticate/signin')
26571058     
26581059    \end{verbatim}
26591060    \end{frame}
26601061   
26611062    \subsection{Conceptos avanzados}
26621063    \begin{frame}[fragile]
26631064    \begin{verbatim}
26641065    Otros conceptos
26651066   
26661067    * Internacionalización
26671068    * Zonas Horarias
26681069    * Servidor Web
26691070    * Geodjango
26701071    * Django Rest
26711072   
26721073     Entre otros...
26731074   
26741075    \end{verbatim}
26751076    \end{frame}
26761077   
26771078    \begin{frame}[plain]
26781079   
26791080     
26801081          \begin{center}
26811082   
26821083            \font\endfont = cmss10 at 15.40mm
26831084            \color{Brown}
26841085            \endfont 
26851086            \baselineskip 20.0mm
26861087   
26871088            CENDITEL
26881089   
26891090          \end{center}   
26901091   
26911092       
26921093    \end{frame}
26931094   
26941095   
26951096    \end{document}
2696>>>>>>> 392f76c82d86075e983cee03fa4b240023981610
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.