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 |
---|
47 | 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. |
---|
48 | https://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 | |
---|
57 | 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 |
---|
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 |
---|
66 | Introducción |
---|
67 | \item |
---|
68 | Configurar ambiente de trabajo |
---|
69 | \item |
---|
70 | Crear proyecto |
---|
71 | \item |
---|
72 | Crear aplicaciones y estructura del proyecto |
---|
73 | \item |
---|
74 | Modelos y migraciones |
---|
75 | \item |
---|
76 | Relaciones |
---|
77 | \item |
---|
78 | Django shell y Querysets |
---|
79 | \item |
---|
80 | Configurar URLs y primera views |
---|
81 | \item |
---|
82 | Sistema de plantillas |
---|
83 | \item |
---|
84 | Configurar archivos estáticos |
---|
85 | \item |
---|
86 | Listar Registros |
---|
87 | \item |
---|
88 | Formularios y vista para anexar registros |
---|
89 | \item |
---|
90 | Vistas 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 |
---|
100 | ListView, CreateView, UpdateView, DeleteView |
---|
101 | \item |
---|
102 | Crear Login |
---|
103 | \item |
---|
104 | Registro de Usuarios |
---|
105 | \item |
---|
106 | Decorador Login required |
---|
107 | \item |
---|
108 | Recuperar contraseña por correo |
---|
109 | \item |
---|
110 | Introducció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} |
---|
120 | Django: Es un entorno de trabajo para el desarrollo Web, basado en el lenguaje de programación Python. |
---|
121 | |
---|
122 | 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. |
---|
123 | |
---|
124 | 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. |
---|
125 | |
---|
126 | Por 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 | |
---|
141 | https://www.djangoproject.com/ |
---|
142 | |
---|
143 | Instalación |
---|
144 | |
---|
145 | https://docs.djangoproject.com/en/1.11/intro/install |
---|
146 | |
---|
147 | Descarga: |
---|
148 | |
---|
149 | https://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 | |
---|
159 | tar -xzvf Django1.11.tar.gz |
---|
160 | |
---|
161 | cd Django1.11 |
---|
162 | |
---|
163 | python setup.py install |
---|
164 | |
---|
165 | // Comprobar la instalación del framework: |
---|
166 | |
---|
167 | python |
---|
168 | import django |
---|
169 | django.VERSION |
---|
170 | |
---|
171 | Ctrl + 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 | |
---|
181 | django-admin startproject curso |
---|
182 | |
---|
183 | // este comando crea la siguiente infraestructura |
---|
184 | de carpetas y archivos: |
---|
185 | |
---|
186 | curso/ |
---|
187 | manage.py |
---|
188 | curso/ |
---|
189 | __init__.py |
---|
190 | settings.py |
---|
191 | urls.py |
---|
192 | wsgi.py |
---|
193 | |
---|
194 | |
---|
195 | Configurar 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 |
---|
204 | Datos Postgresql y la librerÃa de conexión psycopg2 |
---|
205 | // Creamos la base de datos: |
---|
206 | su postgres |
---|
207 | psql |
---|
208 | CREATE USER administrador; |
---|
209 | CREATE DATABASE curso; |
---|
210 | |
---|
211 | // Se edita el archivo curso/settings.py la constante |
---|
212 | DATABASES = { |
---|
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 |
---|
227 | crear las tablas iniciales del proyecto: |
---|
228 | |
---|
229 | python manage.py migrate |
---|
230 | |
---|
231 | // Se ejcuta el comando para crear el superusuario o |
---|
232 | usuario administrador del proyecto: |
---|
233 | |
---|
234 | python manage.py createsuperuser |
---|
235 | |
---|
236 | // Se introducen los datos que solicita |
---|
237 | // Se ejecuta el siguiente comando para activar el |
---|
238 | servidor de prueba de forma local |
---|
239 | |
---|
240 | python manage.py runserver |
---|
241 | \end{verbatim} |
---|
242 | \end{frame} |
---|
243 | |
---|
244 | \begin{frame}[fragile] |
---|
245 | \begin{verbatim} |
---|
246 | python manage.py runserver |
---|
247 | |
---|
248 | // Arroja el siguiente mensaje |
---|
249 | Performing system checks... |
---|
250 | |
---|
251 | System check identified no issues (0 silenced). |
---|
252 | |
---|
253 | July 26, 2017 - 15:32:30 |
---|
254 | Django version 1.11.3,using settings 'curso.settings' |
---|
255 | Starting development server at http://127.0.0.1:8000/ |
---|
256 | Quit the server with CONTROL-C. |
---|
257 | |
---|
258 | // Abrimos el navegador de preferencia y colocamos la |
---|
259 | siguiente dirección para acceder al sistema |
---|
260 | administrativo del proyecto: |
---|
261 | |
---|
262 | http://localhost:8000/admin |
---|
263 | \end{verbatim} |
---|
264 | \end{frame} |
---|
265 | |
---|
266 | \subsection{Crear aplicaciones} |
---|
267 | \begin{frame}[fragile] |
---|
268 | \begin{verbatim} |
---|
269 | |
---|
270 | http://localhost:8000/admin |
---|
271 | |
---|
272 | // En el debemos autenticarnos con el usuario y |
---|
273 | password del superusuario creado en los pasos |
---|
274 | anteriores |
---|
275 | |
---|
276 | // Allà podemos gestionar los usuarios del sistema |
---|
277 | asà como los grupos que evenctualmente se utilizan |
---|
278 | para asignar permisos de acceso. |
---|
279 | |
---|
280 | // En el terminal presionar las teclas Ctrl + C para |
---|
281 | interrumpir la ejecución del servidor y asà crear |
---|
282 | las aplicaciones del proyecto. |
---|
283 | |
---|
284 | python manage.py startapp encuesta |
---|
285 | |
---|
286 | \end{verbatim} |
---|
287 | \end{frame} |
---|
288 | |
---|
289 | \subsection{Modelos} |
---|
290 | \begin{frame}[fragile] |
---|
291 | \begin{verbatim} |
---|
292 | python manage.py startapp encuesta |
---|
293 | |
---|
294 | // Se edita el archivo encuesta/models.py |
---|
295 | |
---|
296 | from django.db import models |
---|
297 | |
---|
298 | class Question(models.Model): |
---|
299 | question_text = models.CharField(max_length=200) |
---|
300 | pub_date =models.DateTimeField('date published') |
---|
301 | |
---|
302 | class 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 |
---|
314 | curso/settings.py la constante: |
---|
315 | |
---|
316 | INSTALLED_APPS = [ |
---|
317 | ... |
---|
318 | 'django.contrib.staticfiles', |
---|
319 | 'encuesta', |
---|
320 | ] |
---|
321 | |
---|
322 | // Para crear las tablas correspondiente de models.py |
---|
323 | se ejecuta el comando: |
---|
324 | |
---|
325 | python manage.py makemigrations encuesta |
---|
326 | |
---|
327 | python 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 |
---|
336 | framework se puede realizar desde el terminal |
---|
337 | con el comando: |
---|
338 | |
---|
339 | python 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 | |
---|
351 | from encuesta.models import Question, Choice |
---|
352 | from django.utils import timezone |
---|
353 | |
---|
354 | Question.objects.all() |
---|
355 | q = Question(question_text="Que hay de nuevo?", |
---|
356 | pub_date=timezone.now()) |
---|
357 | q.save() |
---|
358 | q.id |
---|
359 | q.question_text |
---|
360 | q.pub_date |
---|
361 | q.question_text = "Q ai d nuevo?" |
---|
362 | q.save() |
---|
363 | |
---|
364 | Ctril + D para salir |
---|
365 | \end{verbatim} |
---|
366 | \end{frame} |
---|
367 | |
---|
368 | \begin{frame}[fragile] |
---|
369 | \begin{verbatim} |
---|
370 | Editamos nuevamente el archivo encuesta/models.py |
---|
371 | para añadir el sigueinte metodo a la clase Question |
---|
372 | |
---|
373 | import datetime |
---|
374 | |
---|
375 | from django.db import models |
---|
376 | from django.utils import timezone |
---|
377 | |
---|
378 | class Question(models.Model): |
---|
379 | # ... |
---|
380 | def was_published_recently(self): |
---|
381 | return self.pub_date >= timezone.now() - |
---|
382 | datetime.timedelta(days=1) |
---|
383 | |
---|
384 | Guardamos y volvemos a terminal: |
---|
385 | |
---|
386 | python manage.py shell |
---|
387 | |
---|
388 | \end{verbatim} |
---|
389 | \end{frame} |
---|
390 | |
---|
391 | \begin{frame}[fragile] |
---|
392 | \begin{verbatim} |
---|
393 | from polls.models import Question, Choice |
---|
394 | |
---|
395 | Question.objects.all() |
---|
396 | q = Question.objects.get(pk=1) |
---|
397 | q.was_published_recently() |
---|
398 | |
---|
399 | q = Question.objects.filter(id=1) |
---|
400 | |
---|
401 | q = Question.objects.filter( |
---|
402 | question_text__startswith='Q') |
---|
403 | |
---|
404 | from django.utils import timezone |
---|
405 | current_year = timezone.now().year |
---|
406 | Question.objects.get(pub_date__year=current_year) |
---|
407 | |
---|
408 | Question.objects.get(id=2) Error... |
---|
409 | \end{verbatim} |
---|
410 | \end{frame} |
---|
411 | |
---|
412 | \begin{frame}[fragile] |
---|
413 | \begin{verbatim} |
---|
414 | q = Question.objects.get(pk=1) |
---|
415 | q.choice_set.all() |
---|
416 | q.choice_set.create(choice_text='No mucho', votes=0) |
---|
417 | q.choice_set.create(choice_text='Muchas cosas' |
---|
418 | ,votes=0) |
---|
419 | c = q.choice_set.create(choice_text='De todo un poco' |
---|
420 | ,votes=0) |
---|
421 | |
---|
422 | c.question |
---|
423 | |
---|
424 | q.choice_set.all() |
---|
425 | q.choice_set.count() |
---|
426 | |
---|
427 | Crtl + D para salir |
---|
428 | |
---|
429 | \end{verbatim} |
---|
430 | \end{frame} |
---|
431 | |
---|
432 | \begin{frame}[fragile] |
---|
433 | \begin{verbatim} |
---|
434 | Incluir el modelo de la aplicación encuesta |
---|
435 | en el sistema admin: |
---|
436 | |
---|
437 | Editamos el archivo encuesta/admin.py |
---|
438 | from django.contrib import admin |
---|
439 | |
---|
440 | from .models import Question |
---|
441 | |
---|
442 | admin.site.register(Question) |
---|
443 | |
---|
444 | Guardamos y ejecutamos el servidor |
---|
445 | de prueba nuevamente: |
---|
446 | |
---|
447 | python manage.py runserver |
---|
448 | |
---|
449 | en 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} |
---|
457 | Crear la primera vista para acceso del proyecto |
---|
458 | Editamos el archivo encuesta/urls.py |
---|
459 | |
---|
460 | from django.conf.urls import url |
---|
461 | from . import views |
---|
462 | urlpatterns = [ |
---|
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} |
---|
480 | Editamos el archivo encuesta/views.py: |
---|
481 | |
---|
482 | from django.http import HttpResponse |
---|
483 | from .models import Question |
---|
484 | |
---|
485 | def 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 | |
---|
490 | def detail(request, question_id): |
---|
491 | return HttpResponse("Question No: %s." % question_id) |
---|
492 | |
---|
493 | def results(request, question_id): |
---|
494 | response = "Results of question %s." |
---|
495 | return HttpResponse(response % question_id) |
---|
496 | |
---|
497 | def 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} |
---|
504 | Guardamos y ejecutamos el servidor de prueba y |
---|
505 | probamos los enlaces desde el navegador: |
---|
506 | |
---|
507 | python manage.py runserver |
---|
508 | |
---|
509 | En el navegador probamos los siguientes enlaces: |
---|
510 | |
---|
511 | http://localhost:8000/encueta |
---|
512 | http://localhost:8000/encueta/1 |
---|
513 | http://localhost:8000/encueta/1/result |
---|
514 | http://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} |
---|
523 | Uso del plantillas: |
---|
524 | |
---|
525 | Creamos la siguiente estructura |
---|
526 | |
---|
527 | cd encuesta |
---|
528 | mkdir templates |
---|
529 | mkdir templates/encuesta |
---|
530 | |
---|
531 | y editamos el archivo index.html allà |
---|
532 | |
---|
533 | gedit 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} |
---|
560 | Guardamos y modificamos el archivo encuesta views.py |
---|
561 | para que utilice la plantilla |
---|
562 | |
---|
563 | from django.http import HttpResponse |
---|
564 | from django.template import loader |
---|
565 | |
---|
566 | from .models import Question |
---|
567 | |
---|
568 | |
---|
569 | def 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} |
---|
582 | o utilizando la shortcuts render |
---|
583 | |
---|
584 | from django.shortcuts import render |
---|
585 | |
---|
586 | from .models import Question |
---|
587 | |
---|
588 | |
---|
589 | def 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} |
---|
601 | Descargar plantillas prediseñadas, por ejemplo: |
---|
602 | |
---|
603 | https://adminlte.io/ |
---|
604 | |
---|
605 | Copiar los directorios ccs y js en los en la carpeta static |
---|
606 | |
---|
607 | Copiar los archivo *.html en la carpeta templates |
---|
608 | |
---|
609 | Editar index.html y cambiar los enlaces a cada archivo en: |
---|
610 | |
---|
611 | <link rel="stylesheet" |
---|
612 | href="{% 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} |
---|
620 | Creamos el archivo ajax.py |
---|
621 | |
---|
622 | # -*- encoding: utf-8 -*- |
---|
623 | from django.conf import settings |
---|
624 | from django_datatables_view.base_datatable_view import ( |
---|
625 | BaseDatatableView) |
---|
626 | |
---|
627 | from django.contrib.auth.models import ( |
---|
628 | User) |
---|
629 | |
---|
630 | class 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} |
---|
647 | def 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 |
---|
662 | from .ajax import * |
---|
663 | |
---|
664 | urlpatterns = [ |
---|
665 | .... |
---|
666 | url(r'^listar-users/$', ListUsersAjaxView.as_view(), |
---|
667 | name="listar_users"), |
---|
668 | \end{verbatim} |
---|
669 | \end{frame} |
---|
670 | |
---|
671 | \begin{frame}[fragile] |
---|
672 | \begin{verbatim} |
---|
673 | Se anexa el siguiente código el archivo index.html |
---|
674 | En la parte visual: |
---|
675 | |
---|
676 | <div id="datatable"></div> |
---|
677 | |
---|
678 | Y 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} |
---|
699 | Creamos el método en el archivo views.py |
---|
700 | |
---|
701 | def 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 |
---|
719 | def 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 |
---|
745 | def 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 |
---|
764 | def 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 | |
---|
787 | from django.views.generic.list import ListView |
---|
788 | from django.utils import timezone |
---|
789 | |
---|
790 | from articles.models import Article |
---|
791 | |
---|
792 | class 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 |
---|
809 | from django.conf.urls import url |
---|
810 | |
---|
811 | from article.views import ArticleListView |
---|
812 | |
---|
813 | urlpatterns = [ |
---|
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 | |
---|
837 | from django.views.generic.detail import DetailView |
---|
838 | from django.utils import timezone |
---|
839 | |
---|
840 | from articles.models import Article |
---|
841 | |
---|
842 | class 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 | |
---|
860 | from django.conf.urls import url |
---|
861 | |
---|
862 | from article.views import ArticleDetailView |
---|
863 | |
---|
864 | urlpatterns = [ |
---|
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 | |
---|
883 | from django.views.generic.edit import CreateView |
---|
884 | from myapp.models import Author |
---|
885 | |
---|
886 | class 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 | |
---|
904 | from django.views.generic.edit import UpdateView |
---|
905 | from myapp.models import Author |
---|
906 | |
---|
907 | class 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 | |
---|
926 | from django.views.generic.edit import DeleteView |
---|
927 | from django.urls import reverse_lazy |
---|
928 | from myapp.models import Author |
---|
929 | |
---|
930 | class 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} |
---|
947 | Creamos la aplicacion user desde la consola: |
---|
948 | |
---|
949 | python manage.py startapp user |
---|
950 | |
---|
951 | Editamos el archivo user/views.py: |
---|
952 | |
---|
953 | # -*- coding: utf-8 -*- |
---|
954 | <<<<<<< HEAD |
---|
955 | |
---|
956 | from django.shortcuts import render |
---|
957 | from django.contrib import messages |
---|
958 | from django.contrib.auth import ( |
---|
959 | authenticate, logout, login |
---|
960 | ) |
---|
961 | from django.contrib.auth.models import ( |
---|
962 | Group, Permission, User |
---|
963 | ) |
---|
964 | |
---|
965 | ======= |
---|
966 | |
---|
967 | from django.shortcuts import render |
---|
968 | from django.contrib import messages |
---|
969 | from django.contrib.auth import ( |
---|
970 | authenticate, logout, login |
---|
971 | ) |
---|
972 | from django.contrib.auth.models import ( |
---|
973 | Group, Permission, User |
---|
974 | ) |
---|
975 | |
---|
976 | >>>>>>> f837b9d91ddf1c492cd58e875f097fb99eb9339c |
---|
977 | class 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} |
---|
986 | def 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 | |
---|
1014 | from myapp.models import BlogPost |
---|
1015 | from django.contrib.auth.models import Permission |
---|
1016 | from django.contrib.contenttypes.models import ContentType |
---|
1017 | |
---|
1018 | content_type = ContentType.objects.get_for_model(BlogPost) |
---|
1019 | permission = 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 | |
---|
1031 | from django.contrib.auth.models import Permission, User |
---|
1032 | from django.contrib.contenttypes.models import ContentType |
---|
1033 | from django.shortcuts import get_object_or_404 |
---|
1034 | |
---|
1035 | from myapp.models import BlogPost |
---|
1036 | |
---|
1037 | def 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 | |
---|
1057 | from django.contrib.auth.decorators import |
---|
1058 | login_required, permission_required |
---|
1059 | from django.views.generic import TemplateView |
---|
1060 | |
---|
1061 | from .views import VoteView |
---|
1062 | |
---|
1063 | urlpatterns = [ |
---|
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} |
---|
1076 | def 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} |
---|
1101 | Otros 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} |
---|
1119 | Para la gestión de datos geolocalizados debe utilizar |
---|
1120 | una extensión de django denominada Geodjango |
---|
1121 | |
---|
1122 | Instalación de componentes para la gestión de mapas |
---|
1123 | en particular la extensión django.contrib.gis |
---|
1124 | |
---|
1125 | Entrar como root para la instalacion |
---|
1126 | |
---|
1127 | aptitude install python3.4 python3-pip python3.4-dev |
---|
1128 | python3-setuptools |
---|
1129 | |
---|
1130 | aptitude install python3-virtualenv virtualenvwrapper |
---|
1131 | |
---|
1132 | Salir 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} |
---|
1140 | Instalar los requerimientos del proyecto |
---|
1141 | |
---|
1142 | Para activar el ambiente virtual geodjango ejecute el comando: |
---|
1143 | |
---|
1144 | $ workon geodjango |
---|
1145 | |
---|
1146 | Quedando activado el entorno virtual de esta manera. |
---|
1147 | |
---|
1148 | (geodjango)$ |
---|
1149 | |
---|
1150 | Crear el archivo requerimientos.txt |
---|
1151 | vim requerimientos.txt |
---|
1152 | |
---|
1153 | *** Inicio del archivo requerimientos.txt |
---|
1154 | Django==1.11.4 |
---|
1155 | psycopg2==2.7.1 |
---|
1156 | pytz==2017.2 |
---|
1157 | *** fin del archivo requeimientos.txt |
---|
1158 | |
---|
1159 | Ejecutar el comando de descarga e instalación |
---|
1160 | pip install -r requeimientos.txt |
---|
1161 | \end{verbatim} |
---|
1162 | \end{frame} |
---|
1163 | |
---|
1164 | \begin{frame}[fragile] |
---|
1165 | \begin{verbatim} |
---|
1166 | Crear el proyecto geodjango-demo |
---|
1167 | |
---|
1168 | django-admin startproject geodjango-demo |
---|
1169 | |
---|
1170 | cd geodjango-demo |
---|
1171 | |
---|
1172 | Crear base de datos y Migrar los modelos |
---|
1173 | >>>>>>> f837b9d91ddf1c492cd58e875f097fb99eb9339c |
---|
1174 | |
---|
1175 | Como super usuario instalar postgis: |
---|
1176 | |
---|
1177 | aptitude install postgis |
---|
1178 | |
---|
1179 | aptitude install postgresql-x.x-postgis-x.x |
---|
1180 | |
---|
1181 | Nota: las x.x debe ser sustituidad por la versión de |
---|
1182 | Postgres instalada |
---|
1183 | \end{verbatim} |
---|
1184 | \end{frame} |
---|
1185 | |
---|
1186 | <<<<<<< HEAD |
---|
1187 | ======= |
---|
1188 | \begin{frame}[fragile] |
---|
1189 | \begin{verbatim} |
---|
1190 | Ingresar a la consola de postgres con la siguiente orden: |
---|
1191 | $ psql |
---|
1192 | |
---|
1193 | Ejecutar la siguiente sentencia estando en la consola de |
---|
1194 | postgres: |
---|
1195 | |
---|
1196 | postgres=# CREATE DATABASE geodjango OWNER=postgres; |
---|
1197 | postgres=# \q |
---|
1198 | |
---|
1199 | $ psql geodjango |
---|
1200 | |
---|
1201 | geodjango=# CREATE EXTENSION postgis; |
---|
1202 | geodjango=# \q |
---|
1203 | |
---|
1204 | Editar el archivo geodjango-demo/settings.py |
---|
1205 | |
---|
1206 | INSTALLED_APPS = [ |
---|
1207 | ... |
---|
1208 | 'django.contrib.gis', |
---|
1209 | ] |
---|
1210 | \end{verbatim} |
---|
1211 | \end{frame} |
---|
1212 | |
---|
1213 | \begin{frame}[fragile] |
---|
1214 | \begin{verbatim} |
---|
1215 | Modificar la conexión para la base de datos: |
---|
1216 | |
---|
1217 | DATABASES = { |
---|
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 | |
---|
1230 | Para migrar los modelos del proyecto se debe usar |
---|
1231 | el 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} |
---|
1241 | Creamos la aplicación geolocation |
---|
1242 | (geodjango)$ python manage.py startapp geolocation |
---|
1243 | |
---|
1244 | Creamos el archivos geolocation/urls.py |
---|
1245 | # -*- coding: utf-8 -*- |
---|
1246 | from django.conf.urls import url |
---|
1247 | from .views import * |
---|
1248 | urlpatterns = [ |
---|
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} |
---|
1267 | Modificar el archivo geolocation/views.py |
---|
1268 | |
---|
1269 | # -*- coding: utf-8 -*- |
---|
1270 | from django.contrib import messages |
---|
1271 | from django.contrib.messages.views import SuccessMessageMixin |
---|
1272 | from django.urls import reverse_lazy |
---|
1273 | from django.views.generic.edit import ( |
---|
1274 | FormView, DeleteView, UpdateView |
---|
1275 | ) |
---|
1276 | from django.views.generic import ListView |
---|
1277 | |
---|
1278 | from .forms import * |
---|
1279 | from .models import * |
---|
1280 | |
---|
1281 | \end{verbatim} |
---|
1282 | \end{frame} |
---|
1283 | |
---|
1284 | \begin{frame}[fragile] |
---|
1285 | \begin{verbatim} |
---|
1286 | class 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) |
---|
1295 | class ListZipcodeView(ListView): |
---|
1296 | model = Zipcode |
---|
1297 | template_name = 'geodjango-list.html' |
---|
1298 | paginate_by = 3 |
---|
1299 | class ZipcodeDeleteView(DeleteView): |
---|
1300 | model = Zipcode |
---|
1301 | success_url = reverse_lazy('geolocation:list_zipcode') |
---|
1302 | class 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} |
---|
1312 | Editar el archivo admin.py |
---|
1313 | # -*- coding: utf-8 -*- |
---|
1314 | from django.contrib.gis import admin |
---|
1315 | from .models import * |
---|
1316 | admin.site.register(Zipcode, admin.OSMGeoAdmin) |
---|
1317 | |
---|
1318 | Editar el archivo apps.py |
---|
1319 | from django.apps import AppConfig |
---|
1320 | class GeolocationConfig(AppConfig): |
---|
1321 | name = 'geolocation' |
---|
1322 | |
---|
1323 | Editar el archivo forms.py |
---|
1324 | # -*- coding: utf-8 -*- |
---|
1325 | from django.contrib.gis import forms |
---|
1326 | from .models import * |
---|
1327 | |
---|
1328 | class 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} |
---|
1364 | Editar el archivo models.py |
---|
1365 | # -*- coding: utf-8 -*- |
---|
1366 | from django.contrib.gis.db import models |
---|
1367 | |
---|
1368 | class 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 |
---|
1377 | class 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} |
---|
1391 | Editar el archivo geodjango-demo/settings.py |
---|
1392 | |
---|
1393 | INSTALLED_APPS = [ |
---|
1394 | ... |
---|
1395 | 'django.contrib.gis', |
---|
1396 | 'geolocation', |
---|
1397 | ] |
---|
1398 | |
---|
1399 | Guardamos y ejecutamos el comando |
---|
1400 | (geodjango)$ python manage.py makemigrations geolocation |
---|
1401 | (geodjango)$ python manage.py migrate geolocation |
---|
1402 | |
---|
1403 | Editamos el Templates para lo cual creamos la carpeta templates |
---|
1404 | y creamos los archivos geodjango-template.html y |
---|
1405 | geodjango-list.html |
---|
1406 | |
---|
1407 | mkdir geolocation/templates |
---|
1408 | cd geolocation/templates |
---|
1409 | |
---|
1410 | \end{verbatim} |
---|
1411 | \end{frame} |
---|
1412 | |
---|
1413 | \begin{frame}[fragile] |
---|
1414 | \begin{verbatim} |
---|
1415 | Archivo 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 %} › {{ 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"> |
---|
1473 | Pá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 %} › {{ 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 }} |
---|
1522 | options['default_lon'] = {{ default_lon|unlocalize }}; |
---|
1523 | options['default_lat'] = {{ default_lat|unlocalize }}; |
---|
1524 | options['default_zoom'] = {{ default_zoom|unlocalize }}; |
---|
1525 | {% endblock %} |
---|
1526 | |
---|
1527 | {% block base_layer %} |
---|
1528 | var 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> </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} |
---|
1558 | Editar el archivo geodjango-demo/urls.py |
---|
1559 | |
---|
1560 | from django.conf.urls import url, include |
---|
1561 | from django.contrib.gis import admin |
---|
1562 | |
---|
1563 | urlpatterns = [ |
---|
1564 | url(r'^admin/', admin.site.urls), |
---|
1565 | url(r'^geolocation/', include('geolocation.urls', |
---|
1566 | namespace="geolocation")), |
---|
1567 | ] |
---|
1568 | |
---|
1569 | Guardar y ahora se puede ejecutar el comando |
---|
1570 | |
---|
1571 | (geodjango)$ python manage.py runserver |
---|
1572 | |
---|
1573 | Y acceder desde un navegador la dirección |
---|
1574 | |
---|
1575 | http://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 | ======= |
---|
1601 | 2 \usetheme{Berkeley} |
---|
1602 | 3 \usepackage[spanish]{babel} |
---|
1603 | 4 \usepackage[utf8]{inputenc} |
---|
1604 | 5 \usepackage[T1]{fontenc} |
---|
1605 | 6 \usepackage{lmodern} |
---|
1606 | 7 \usepackage{fancyhdr} |
---|
1607 | 8 \usepackage{graphicx} |
---|
1608 | 9 \usepackage{mathrsfs} |
---|
1609 | 10 \usepackage{amsmath} |
---|
1610 | 11 \usepackage{lmodern} |
---|
1611 | 12 \usepackage{multimedia} |
---|
1612 | 13 \usepackage{hyperref} |
---|
1613 | 14 \usepackage{varioref} |
---|
1614 | 15 \usepackage{ragged2e} |
---|
1615 | 16 \usepackage{etoolbox} |
---|
1616 | 17 \usepackage{lipsum} |
---|
1617 | 18 \usepackage{fancyvrb} |
---|
1618 | 19 \fvset{fontsize=\footnotesize} |
---|
1619 | 20 \RecustomVerbatimEnvironment{verbatim}{Verbatim}{} |
---|
1620 | 21 \apptocmd{\frame}{}{\justifying}{} % Allow optional arguments after frame. |
---|
1621 | 22 \usecolortheme[{rgb={0.6,0,0}}]{structure} |
---|
1622 | 23 \setbeamercovered{transparent} |
---|
1623 | 24 \setbeamertemplate{items}[ball] |
---|
1624 | 25 \setbeamertemplate{blocks}[rounded][shadow=true] |
---|
1625 | 26 \beamertemplateshadingbackground{gray!50}{white!50} |
---|
1626 | 27 \newtheorem{Ejemplo}{Django} |
---|
1627 | 28 \useoutertheme{infolines} |
---|
1628 | 29 \title []{Framework Django 1.11} |
---|
1629 | 30 \author{Instructor Ing. Erwin Paredes} |
---|
1630 | 31 %\logo{ \includegraphics[height=3cm]{figura/logo-blanco2.png}} |
---|
1631 | 32 \institute{CENDITEL} |
---|
1632 | 33 \date{\today} |
---|
1633 | 34 |
---|
1634 | 35 \begin{document} |
---|
1635 | 36 |
---|
1636 | 37 \section{Cenditel} |
---|
1637 | 38 \begin{frame} |
---|
1638 | 39 \maketitle |
---|
1639 | 40 \end{frame} |
---|
1640 | 41 |
---|
1641 | 42 \subsection{La Fundación} |
---|
1642 | 43 \begin{frame} |
---|
1643 | 44 \begin{block}{Fundación CENDITEL} |
---|
1644 | 45 \indent |
---|
1645 | 46 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. |
---|
1646 | 47 https://www.cenditel.gob.ve |
---|
1647 | 48 |
---|
1648 | 49 \end{block} |
---|
1649 | 50 \end{frame} |
---|
1650 | 51 |
---|
1651 | 52 \subsection{Finalidad del Curso} |
---|
1652 | 53 \begin{frame} |
---|
1653 | 54 \begin{block}{Finalidad} |
---|
1654 | 55 |
---|
1655 | 56 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 |
---|
1656 | 57 \end{block} |
---|
1657 | 58 \end{frame} |
---|
1658 | 59 |
---|
1659 | 60 \subsection{Contenido del Curso} |
---|
1660 | 61 \begin{frame} |
---|
1661 | 62 \begin{block}{Contenido del Curso} |
---|
1662 | 63 \begin{itemize} |
---|
1663 | 64 \item |
---|
1664 | 65 Introducción |
---|
1665 | 66 \item |
---|
1666 | 67 Configurar ambiente de trabajo |
---|
1667 | 68 \item |
---|
1668 | 69 Crear proyecto |
---|
1669 | 70 \item |
---|
1670 | 71 Crear aplicaciones y estructura del proyecto |
---|
1671 | 72 \item |
---|
1672 | 73 Modelos y migraciones |
---|
1673 | 74 \item |
---|
1674 | 75 Relaciones |
---|
1675 | 76 \item |
---|
1676 | 77 Django shell y Querysets |
---|
1677 | 78 \item |
---|
1678 | 79 Configurar URLs y primera views |
---|
1679 | 80 \item |
---|
1680 | 81 Sistema de plantillas |
---|
1681 | 82 \item |
---|
1682 | 83 Configurar archivos estáticos |
---|
1683 | 84 \item |
---|
1684 | 85 Listar Registros |
---|
1685 | 86 \item |
---|
1686 | 87 Formularios y vista para anexar registros |
---|
1687 | 88 \item |
---|
1688 | 89 Vistas para modificar y eliminar registros |
---|
1689 | 90 \end{itemize} |
---|
1690 | 91 \end{block} |
---|
1691 | 92 \end{frame} |
---|
1692 | 93 |
---|
1693 | 94 |
---|
1694 | 95 \begin{frame} |
---|
1695 | 96 \begin{block}{Contenido del Curso} |
---|
1696 | 97 \begin{itemize} |
---|
1697 | 98 \item |
---|
1698 | 99 ListView, CreateView, UpdateView, DeleteView |
---|
1699 | 100 \item |
---|
1700 | 101 Crear Login |
---|
1701 | 102 \item |
---|
1702 | 103 Registro de Usuarios |
---|
1703 | 104 \item |
---|
1704 | 105 Decorador Login required |
---|
1705 | 106 \item |
---|
1706 | 107 Recuperar contraseña por correo |
---|
1707 | 108 \item |
---|
1708 | 109 Introducción a conceptos avanzados |
---|
1709 | 110 \end{itemize} |
---|
1710 | 111 \end{block} |
---|
1711 | 112 \end{frame} |
---|
1712 | 113 |
---|
1713 | 114 |
---|
1714 | 115 |
---|
1715 | 116 \section{Django} |
---|
1716 | 117 \subsection{Introducción} |
---|
1717 | 118 \begin{frame} |
---|
1718 | 119 Django: Es un entorno de trabajo para el desarrollo Web, basado en el lenguaje de programación Python. |
---|
1719 | 120 |
---|
1720 | 121 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. |
---|
1721 | 122 |
---|
1722 | 123 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. |
---|
1723 | 124 |
---|
1724 | 125 Por lo que para cada aplicación o módulo que conforma el proyecto se agrupa en lo siguientes archivos: |
---|
1725 | 126 |
---|
1726 | 127 \begin{itemize} |
---|
1727 | 128 \item models.py :Contiene las clases que definen la estructura de datos |
---|
1728 | 129 \item views.py :Contiene la codificación de las funcionalidades que permiten controlar el comportamiento del sistema. |
---|
1729 | 130 \item *.html :Contiene la codificación de la interfaz |
---|
1730 | 131 \end{itemize} |
---|
1731 | 132 \end{frame} |
---|
1732 | 133 |
---|
1733 | 134 \subsection{Configurar ambiente de trabajo} |
---|
1734 | 135 \begin{frame}[fragile] |
---|
1735 | 136 |
---|
1736 | 137 \begin{Large}\textbf{Sitio Oficial}\end{Large} |
---|
1737 | 138 \begin{verbatim} |
---|
1738 | 139 |
---|
1739 | 140 https://www.djangoproject.com/ |
---|
1740 | 141 |
---|
1741 | 142 Instalación |
---|
1742 | 143 |
---|
1743 | 144 https://docs.djangoproject.com/en/1.11/intro/install |
---|
1744 | 145 |
---|
1745 | 146 Descarga: |
---|
1746 | 147 |
---|
1747 | 148 https://www.djangoproject.com/download/ |
---|
1748 | 149 \end{verbatim} |
---|
1749 | 150 \end{frame} |
---|
1750 | 151 |
---|
1751 | 152 \begin{frame}[fragile] |
---|
1752 | 153 |
---|
1753 | 154 \begin{Large}\textbf{Instalación}\end{Large} |
---|
1754 | 155 \begin{verbatim} |
---|
1755 | 156 // Descomprimir el archivo |
---|
1756 | 157 |
---|
1757 | 158 tar -xzvf Django1.11.tar.gz |
---|
1758 | 159 |
---|
1759 | 160 cd Django1.11 |
---|
1760 | 161 |
---|
1761 | 162 python setup.py install |
---|
1762 | 163 |
---|
1763 | 164 // Comprobar la instalación del framework: |
---|
1764 | 165 |
---|
1765 | 166 python |
---|
1766 | 167 import django |
---|
1767 | 168 django.VERSION |
---|
1768 | 169 |
---|
1769 | 170 Ctrl + D |
---|
1770 | 171 \end{verbatim} |
---|
1771 | 172 \end{frame} |
---|
1772 | 173 |
---|
1773 | 174 \subsection{Crear proyecto} |
---|
1774 | 175 \begin{frame}[fragile] |
---|
1775 | 176 |
---|
1776 | 177 \begin{verbatim} |
---|
1777 | 178 // Crear el primer proyecto: |
---|
1778 | 179 |
---|
1779 | 180 django-admin startproject curso |
---|
1780 | 181 |
---|
1781 | 182 // este comando crea la siguiente infraestructura |
---|
1782 | 183 de carpetas y archivos: |
---|
1783 | 184 |
---|
1784 | 185 curso/ |
---|
1785 | 186 manage.py |
---|
1786 | 187 curso/ |
---|
1787 | 188 __init__.py |
---|
1788 | 189 settings.py |
---|
1789 | 190 urls.py |
---|
1790 | 191 wsgi.py |
---|
1791 | 192 |
---|
1792 | 193 |
---|
1793 | 194 Configurar la base de datos |
---|
1794 | 195 |
---|
1795 | 196 \end{verbatim} |
---|
1796 | 197 \end{frame} |
---|
1797 | 198 |
---|
1798 | 199 \begin{frame}[fragile] |
---|
1799 | 200 |
---|
1800 | 201 \begin{verbatim} |
---|
1801 | 202 // Se debe haber instalado el gestor de la Base de |
---|
1802 | 203 Datos Postgresql y la librerÃÂa de conexión psycopg2 |
---|
1803 | 204 // Creamos la base de datos: |
---|
1804 | 205 su postgres |
---|
1805 | 206 psql |
---|
1806 | 207 CREATE USER administrador; |
---|
1807 | 208 CREATE DATABASE curso; |
---|
1808 | 209 |
---|
1809 | 210 // Se edita el archivo curso/settings.py la constante |
---|
1810 | 211 DATABASES = { |
---|
1811 | 212 'default': { |
---|
1812 | 213 'ENGINE': 'django.db.backends.postgresql', |
---|
1813 | 214 'NAME': 'curso', |
---|
1814 | 215 'USER': 'administrador', |
---|
1815 | 216 'PASSWORD': 'clave', |
---|
1816 | 217 'HOST': '127.0.0.1', |
---|
1817 | 218 'PORT': '5432', |
---|
1818 | 219 } } |
---|
1819 | 220 \end{verbatim} |
---|
1820 | 221 \end{frame} |
---|
1821 | 222 |
---|
1822 | 223 \begin{frame}[fragile] |
---|
1823 | 224 \begin{verbatim} |
---|
1824 | 225 // Se guarda y ejecuta el siguiente comando para |
---|
1825 | 226 crear las tablas iniciales del proyecto: |
---|
1826 | 227 |
---|
1827 | 228 python manage.py migrate |
---|
1828 | 229 |
---|
1829 | 230 // Se ejcuta el comando para crear el superusuario o |
---|
1830 | 231 usuario administrador del proyecto: |
---|
1831 | 232 |
---|
1832 | 233 python manage.py createsuperuser |
---|
1833 | 234 |
---|
1834 | 235 // Se introducen los datos que solicita |
---|
1835 | 236 // Se ejecuta el siguiente comando para activar el |
---|
1836 | 237 servidor de prueba de forma local |
---|
1837 | 238 |
---|
1838 | 239 python manage.py runserver |
---|
1839 | 240 \end{verbatim} |
---|
1840 | 241 \end{frame} |
---|
1841 | 242 |
---|
1842 | 243 \begin{frame}[fragile] |
---|
1843 | 244 \begin{verbatim} |
---|
1844 | 245 python manage.py runserver |
---|
1845 | 246 |
---|
1846 | 247 // Arroja el siguiente mensaje |
---|
1847 | 248 Performing system checks... |
---|
1848 | 249 |
---|
1849 | 250 System check identified no issues (0 silenced). |
---|
1850 | 251 |
---|
1851 | 252 July 26, 2017 - 15:32:30 |
---|
1852 | 253 Django version 1.11.3,using settings 'curso.settings' |
---|
1853 | 254 Starting development server at http://127.0.0.1:8000/ |
---|
1854 | 255 Quit the server with CONTROL-C. |
---|
1855 | 256 |
---|
1856 | 257 // Abrimos el navegador de preferencia y colocamos la |
---|
1857 | 258 siguiente dirección para acceder al sistema |
---|
1858 | 259 administrativo del proyecto: |
---|
1859 | 260 |
---|
1860 | 261 http://localhost:8000/admin |
---|
1861 | 262 \end{verbatim} |
---|
1862 | 263 \end{frame} |
---|
1863 | 264 |
---|
1864 | 265 \subsection{Crear aplicaciones} |
---|
1865 | 266 \begin{frame}[fragile] |
---|
1866 | 267 \begin{verbatim} |
---|
1867 | 268 |
---|
1868 | 269 http://localhost:8000/admin |
---|
1869 | 270 |
---|
1870 | 271 // En el debemos autenticarnos con el usuario y |
---|
1871 | 272 password del superusuario creado en los pasos |
---|
1872 | 273 anteriores |
---|
1873 | 274 |
---|
1874 | 275 // AllÃÂ podemos gestionar los usuarios del sistema |
---|
1875 | 276 asÃÂ como los grupos que evenctualmente se utilizan |
---|
1876 | 277 para asignar permisos de acceso. |
---|
1877 | 278 |
---|
1878 | 279 // En el terminal presionar las teclas Ctrl + C para |
---|
1879 | 280 interrumpir la ejecución del servidor y asàcrear |
---|
1880 | 281 las aplicaciones del proyecto. |
---|
1881 | 282 |
---|
1882 | 283 python manage.py startapp encuesta |
---|
1883 | 284 |
---|
1884 | 285 \end{verbatim} |
---|
1885 | 286 \end{frame} |
---|
1886 | 287 |
---|
1887 | 288 \subsection{Modelos} |
---|
1888 | 289 \begin{frame}[fragile] |
---|
1889 | 290 \begin{verbatim} |
---|
1890 | 291 python manage.py startapp encuesta |
---|
1891 | 292 |
---|
1892 | 293 // Se edita el archivo encuesta/models.py |
---|
1893 | 294 |
---|
1894 | 295 from django.db import models |
---|
1895 | 296 |
---|
1896 | 297 class Question(models.Model): |
---|
1897 | 298 question_text = models.CharField(max_length=200) |
---|
1898 | 299 pub_date =models.DateTimeField('date published') |
---|
1899 | 300 |
---|
1900 | 301 class Choice(models.Model): |
---|
1901 | 302 question = models.ForeignKey(Question, |
---|
1902 | 303 on_delete=models.CASCADE) |
---|
1903 | 304 choice_text = models.CharField(max_length=200) |
---|
1904 | 305 votes = models.IntegerField(default=0) |
---|
1905 | 306 |
---|
1906 | 307 \end{verbatim} |
---|
1907 | 308 \end{frame} |
---|
1908 | 309 |
---|
1909 | 310 \begin{frame}[fragile] |
---|
1910 | 311 \begin{verbatim} |
---|
1911 | 312 // Almacenamos y editamos el archivo |
---|
1912 | 313 curso/settings.py la constante: |
---|
1913 | 314 |
---|
1914 | 315 INSTALLED_APPS = [ |
---|
1915 | 316 ... |
---|
1916 | 317 'django.contrib.staticfiles', |
---|
1917 | 318 'encuesta', |
---|
1918 | 319 ] |
---|
1919 | 320 |
---|
1920 | 321 // Para crear las tablas correspondiente de models.py |
---|
1921 | 322 se ejecuta el comando: |
---|
1922 | 323 |
---|
1923 | 324 python manage.py makemigrations encuesta |
---|
1924 | 325 |
---|
1925 | 326 python manage.py migrate encuesta |
---|
1926 | 327 |
---|
1927 | 328 \end{verbatim} |
---|
1928 | 329 \end{frame} |
---|
1929 | 330 |
---|
1930 | 331 \subsection{Relaciones} |
---|
1931 | 332 \begin{frame}[fragile] |
---|
1932 | 333 \begin{verbatim} |
---|
1933 | 334 // Para el manejo de las tablas por medio del |
---|
1934 | 335 framework se puede realizar desde el terminal |
---|
1935 | 336 con el comando: |
---|
1936 | 337 |
---|
1937 | 338 python manage.py shell |
---|
1938 | 339 |
---|
1939 | 340 |
---|
1940 | 341 \end{verbatim} |
---|
1941 | 342 \end{frame} |
---|
1942 | 343 |
---|
1943 | 344 \subsection{Django shell y Querysets} |
---|
1944 | 345 \begin{frame}[fragile] |
---|
1945 | 346 \begin{verbatim} |
---|
1946 | 347 |
---|
1947 | 348 // AllÃÂ podemos ejecutar las siguientes instrucciones |
---|
1948 | 349 |
---|
1949 | 350 from encuesta.models import Question, Choice |
---|
1950 | 351 from django.utils import timezone |
---|
1951 | 352 |
---|
1952 | 353 Question.objects.all() |
---|
1953 | 354 q = Question(question_text="Que hay de nuevo?", |
---|
1954 | 355 pub_date=timezone.now()) |
---|
1955 | 356 q.save() |
---|
1956 | 357 q.id |
---|
1957 | 358 q.question_text |
---|
1958 | 359 q.pub_date |
---|
1959 | 360 q.question_text = "Q ai d nuevo?" |
---|
1960 | 361 q.save() |
---|
1961 | 362 |
---|
1962 | 363 Ctril + D para salir |
---|
1963 | 364 \end{verbatim} |
---|
1964 | 365 \end{frame} |
---|
1965 | 366 |
---|
1966 | 367 \begin{frame}[fragile] |
---|
1967 | 368 \begin{verbatim} |
---|
1968 | 369 Editamos nuevamente el archivo encuesta/models.py |
---|
1969 | 370 para añadir el sigueinte metodo a la clase Question |
---|
1970 | 371 |
---|
1971 | 372 import datetime |
---|
1972 | 373 |
---|
1973 | 374 from django.db import models |
---|
1974 | 375 from django.utils import timezone |
---|
1975 | 376 |
---|
1976 | 377 class Question(models.Model): |
---|
1977 | 378 # ... |
---|
1978 | 379 def was_published_recently(self): |
---|
1979 | 380 return self.pub_date >= timezone.now() - |
---|
1980 | 381 datetime.timedelta(days=1) |
---|
1981 | 382 |
---|
1982 | 383 Guardamos y volvemos a terminal: |
---|
1983 | 384 |
---|
1984 | 385 python manage.py shell |
---|
1985 | 386 |
---|
1986 | 387 \end{verbatim} |
---|
1987 | 388 \end{frame} |
---|
1988 | 389 |
---|
1989 | 390 \begin{frame}[fragile] |
---|
1990 | 391 \begin{verbatim} |
---|
1991 | 392 from polls.models import Question, Choice |
---|
1992 | 393 |
---|
1993 | 394 Question.objects.all() |
---|
1994 | 395 q = Question.objects.get(pk=1) |
---|
1995 | 396 q.was_published_recently() |
---|
1996 | 397 |
---|
1997 | 398 q = Question.objects.filter(id=1) |
---|
1998 | 399 |
---|
1999 | 400 q = Question.objects.filter( |
---|
2000 | 401 question_text__startswith='Q') |
---|
2001 | 402 |
---|
2002 | 403 from django.utils import timezone |
---|
2003 | 404 current_year = timezone.now().year |
---|
2004 | 405 Question.objects.get(pub_date__year=current_year) |
---|
2005 | 406 |
---|
2006 | 407 Question.objects.get(id=2) Error... |
---|
2007 | 408 \end{verbatim} |
---|
2008 | 409 \end{frame} |
---|
2009 | 410 |
---|
2010 | 411 \begin{frame}[fragile] |
---|
2011 | 412 \begin{verbatim} |
---|
2012 | 413 q = Question.objects.get(pk=1) |
---|
2013 | 414 q.choice_set.all() |
---|
2014 | 415 q.choice_set.create(choice_text='No mucho', votes=0) |
---|
2015 | 416 q.choice_set.create(choice_text='Muchas cosas' |
---|
2016 | 417 ,votes=0) |
---|
2017 | 418 c = q.choice_set.create(choice_text='De todo un poco' |
---|
2018 | 419 ,votes=0) |
---|
2019 | 420 |
---|
2020 | 421 c.question |
---|
2021 | 422 |
---|
2022 | 423 q.choice_set.all() |
---|
2023 | 424 q.choice_set.count() |
---|
2024 | 425 |
---|
2025 | 426 Crtl + D para salir |
---|
2026 | 427 |
---|
2027 | 428 \end{verbatim} |
---|
2028 | 429 \end{frame} |
---|
2029 | 430 |
---|
2030 | 431 \begin{frame}[fragile] |
---|
2031 | 432 \begin{verbatim} |
---|
2032 | 433 Incluir el modelo de la aplicación encuesta |
---|
2033 | 434 en el sistema admin: |
---|
2034 | 435 |
---|
2035 | 436 Editamos el archivo encuesta/admin.py |
---|
2036 | 437 from django.contrib import admin |
---|
2037 | 438 |
---|
2038 | 439 from .models import Question |
---|
2039 | 440 |
---|
2040 | 441 admin.site.register(Question) |
---|
2041 | 442 |
---|
2042 | 443 Guardamos y ejecutamos el servidor |
---|
2043 | 444 de prueba nuevamente: |
---|
2044 | 445 |
---|
2045 | 446 python manage.py runserver |
---|
2046 | 447 |
---|
2047 | 448 en el navegador http://localhost:8000/admin |
---|
2048 | 449 |
---|
2049 | 450 \end{verbatim} |
---|
2050 | 451 \end{frame} |
---|
2051 | 452 |
---|
2052 | 453 \subsection{Configurar URLs y primera views} |
---|
2053 | 454 \begin{frame}[fragile] |
---|
2054 | 455 \begin{verbatim} |
---|
2055 | 456 Crear la primera vista para acceso del proyecto |
---|
2056 | 457 Editamos el archivo encuesta/urls.py |
---|
2057 | 458 |
---|
2058 | 459 from django.conf.urls import url |
---|
2059 | 460 from . import views |
---|
2060 | 461 urlpatterns = [ |
---|
2061 | 462 # ex: /encueta/ |
---|
2062 | 463 url(r'^$', views.index, name='index'), |
---|
2063 | 464 # ex: /encuesta/5/ |
---|
2064 | 465 url(r'^(?P<question_id>[0-9]+)/$', |
---|
2065 | 466 views.detail, name='detail'), |
---|
2066 | 467 # ex: /encuesta/5/results/ |
---|
2067 | 468 url(r'^(?P<question_id>[0-9]+)/results/$', |
---|
2068 | 469 views.results, name='results'), |
---|
2069 | 470 # ex: /encuesta/5/vote/ |
---|
2070 | 471 url(r'^(?P<question_id>[0-9]+)/vote/$', |
---|
2071 | 472 views.vote, name='vote'), |
---|
2072 | 473 ] |
---|
2073 | 474 \end{verbatim} |
---|
2074 | 475 \end{frame} |
---|
2075 | 476 |
---|
2076 | 477 \begin{frame}[fragile] |
---|
2077 | 478 \begin{verbatim} |
---|
2078 | 479 Editamos el archivo encuesta/views.py: |
---|
2079 | 480 |
---|
2080 | 481 from django.http import HttpResponse |
---|
2081 | 482 from .models import Question |
---|
2082 | 483 |
---|
2083 | 484 def index(request): |
---|
2084 | 485 question_list = Question.objects.order_by('-pub_date')[:5] |
---|
2085 | 486 output = ', '.join([q.question_text for q in question_list]) |
---|
2086 | 487 return HttpResponse(output) |
---|
2087 | 488 |
---|
2088 | 489 def detail(request, question_id): |
---|
2089 | 490 return HttpResponse("Question No: %s." % question_id) |
---|
2090 | 491 |
---|
2091 | 492 def results(request, question_id): |
---|
2092 | 493 response = "Results of question %s." |
---|
2093 | 494 return HttpResponse(response % question_id) |
---|
2094 | 495 |
---|
2095 | 496 def vote(request, question_id): |
---|
2096 | 497 return HttpResponse("Voting on question %s." % question_id) |
---|
2097 | 498 \end{verbatim} |
---|
2098 | 499 \end{frame} |
---|
2099 | 500 |
---|
2100 | 501 \begin{frame}[fragile] |
---|
2101 | 502 \begin{verbatim} |
---|
2102 | 503 Guardamos y ejecutamos el servidor de prueba y |
---|
2103 | 504 probamos los enlaces desde el navegador: |
---|
2104 | 505 |
---|
2105 | 506 python manage.py runserver |
---|
2106 | 507 |
---|
2107 | 508 En el navegador probamos los siguientes enlaces: |
---|
2108 | 509 |
---|
2109 | 510 http://localhost:8000/encueta |
---|
2110 | 511 http://localhost:8000/encueta/1 |
---|
2111 | 512 http://localhost:8000/encueta/1/result |
---|
2112 | 513 http://localhost:8000/encueta/1/vote |
---|
2113 | 514 |
---|
2114 | 515 \end{verbatim} |
---|
2115 | 516 \end{frame} |
---|
2116 | 517 |
---|
2117 | 518 \subsection{Sistema de plantillas} |
---|
2118 | 519 |
---|
2119 | 520 \begin{frame}[fragile] |
---|
2120 | 521 \begin{verbatim} |
---|
2121 | 522 Uso del plantillas: |
---|
2122 | 523 |
---|
2123 | 524 Creamos la siguiente estructura |
---|
2124 | 525 |
---|
2125 | 526 cd encuesta |
---|
2126 | 527 mkdir templates |
---|
2127 | 528 mkdir templates/encuesta |
---|
2128 | 529 |
---|
2129 | 530 y editamos el archivo index.html allÃÂ |
---|
2130 | 531 |
---|
2131 | 532 gedit encuesta/templates/encuesta/index.html |
---|
2132 | 533 |
---|
2133 | 534 \end{verbatim} |
---|
2134 | 535 \end{frame} |
---|
2135 | 536 |
---|
2136 | 537 \begin{frame}[fragile] |
---|
2137 | 538 \begin{verbatim} |
---|
2138 | 539 {% if question_list %} |
---|
2139 | 540 <ul> |
---|
2140 | 541 {% for question in question_list %} |
---|
2141 | 542 <li> |
---|
2142 | 543 <a href="/encuesta/{{ question.id }}/"> |
---|
2143 | 544 {{ |
---|
2144 | 545 question.question_text |
---|
2145 | 546 }} |
---|
2146 | 547 </a> |
---|
2147 | 548 </li> |
---|
2148 | 549 {% endfor %} |
---|
2149 | 550 </ul> |
---|
2150 | 551 {% else %} |
---|
2151 | 552 <p>No hay encuestas.</p> |
---|
2152 | 553 {% endif %} |
---|
2153 | 554 \end{verbatim} |
---|
2154 | 555 \end{frame} |
---|
2155 | 556 |
---|
2156 | 557 \begin{frame}[fragile] |
---|
2157 | 558 \begin{verbatim} |
---|
2158 | 559 Guardamos y modificamos el archivo encuesta views.py |
---|
2159 | 560 para que utilice la plantilla |
---|
2160 | 561 |
---|
2161 | 562 from django.http import HttpResponse |
---|
2162 | 563 from django.template import loader |
---|
2163 | 564 |
---|
2164 | 565 from .models import Question |
---|
2165 | 566 |
---|
2166 | 567 |
---|
2167 | 568 def index(request): |
---|
2168 | 569 question_list = Question.objects.order_by('-pub_date')[:5] |
---|
2169 | 570 template = loader.get_template('polls/index.html') |
---|
2170 | 571 context = { |
---|
2171 | 572 'question_list': question_list, |
---|
2172 | 573 } |
---|
2173 | 574 return HttpResponse(template.render(context, request)) |
---|
2174 | 575 |
---|
2175 | 576 \end{verbatim} |
---|
2176 | 577 \end{frame} |
---|
2177 | 578 |
---|
2178 | 579 \begin{frame}[fragile] |
---|
2179 | 580 \begin{verbatim} |
---|
2180 | 581 o utilizando la shortcuts render |
---|
2181 | 582 |
---|
2182 | 583 from django.shortcuts import render |
---|
2183 | 584 |
---|
2184 | 585 from .models import Question |
---|
2185 | 586 |
---|
2186 | 587 |
---|
2187 | 588 def index(request): |
---|
2188 | 589 question_list = Question.objects.order_by('-pub_date')[:5] |
---|
2189 | 590 context = {'question_list': question_list} |
---|
2190 | 591 return render(request, 'polls/index.html', context) |
---|
2191 | 592 |
---|
2192 | 593 |
---|
2193 | 594 \end{verbatim} |
---|
2194 | 595 \end{frame} |
---|
2195 | 596 |
---|
2196 | 597 \subsection{Configurar estáticos} |
---|
2197 | 598 \begin{frame}[fragile] |
---|
2198 | 599 \begin{verbatim} |
---|
2199 | 600 Descargar plantillas prediseñadas, por ejemplo: |
---|
2200 | 601 |
---|
2201 | 602 https://adminlte.io/ |
---|
2202 | 603 |
---|
2203 | 604 Copiar los directorios ccs y js en los en la carpeta static |
---|
2204 | 605 |
---|
2205 | 606 Copiar los archivo *.html en la carpeta templates |
---|
2206 | 607 |
---|
2207 | 608 Editar index.html y cambiar los enlaces a cada archivo en: |
---|
2208 | 609 |
---|
2209 | 610 <link rel="stylesheet" |
---|
2210 | 611 href="{% static 'css/DataTables/jquery.dataTables.min.css' %}"> |
---|
2211 | 612 |
---|
2212 | 613 \end{verbatim} |
---|
2213 | 614 \end{frame} |
---|
2214 | 615 |
---|
2215 | 616 \subsection{Listar Registros} |
---|
2216 | 617 \begin{frame}[fragile] |
---|
2217 | 618 \begin{verbatim} |
---|
2218 | 619 Creamos el archivo ajax.py |
---|
2219 | 620 |
---|
2220 | 621 # -*- encoding: utf-8 -*- |
---|
2221 | 622 from django.conf import settings |
---|
2222 | 623 from django_datatables_view.base_datatable_view import ( |
---|
2223 | 624 BaseDatatableView) |
---|
2224 | 625 |
---|
2225 | 626 from django.contrib.auth.models import ( |
---|
2226 | 627 User) |
---|
2227 | 628 |
---|
2228 | 629 class ListUsersAjaxView(BaseDatatableView): |
---|
2229 | 630 model = User |
---|
2230 | 631 columns = ['pk','first_name','last_name','username','email', |
---|
2231 | 632 'date_joined', 'last_joined' ] |
---|
2232 | 633 order_columns = ['pk', 'username'] |
---|
2233 | 634 max_display_length = 500 |
---|
2234 | 635 |
---|
2235 | 636 def __init__(self): |
---|
2236 | 637 super(ListUsersAjaxView, self).__init__() |
---|
2237 | 638 |
---|
2238 | 639 def get_initial_queryset(self): |
---|
2239 | 640 return self.model.objects.all() |
---|
2240 | 641 \end{verbatim} |
---|
2241 | 642 \end{frame} |
---|
2242 | 643 |
---|
2243 | 644 \begin{frame}[fragile] |
---|
2244 | 645 \begin{verbatim} |
---|
2245 | 646 def prepare_results(self, qs): |
---|
2246 | 647 json_data = [] |
---|
2247 | 648 for item in qs: |
---|
2248 | 649 json_data.append([ |
---|
2249 | 650 username, |
---|
2250 | 651 "{0} {1}".format(str(item.first_name),str(item.last_name)), |
---|
2251 | 652 item.email, |
---|
2252 | 653 item.date_joined.strftime("%Y-%m-%d %H:%M:%S"), |
---|
2253 | 654 last_login |
---|
2254 | 655 ]) |
---|
2255 | 656 |
---|
2256 | 657 return json_data |
---|
2257 | 658 # Fin del archivo ajax.py |
---|
2258 | 659 |
---|
2259 | 660 #En el archivo urls.py anexar las siguientes lineas |
---|
2260 | 661 from .ajax import * |
---|
2261 | 662 |
---|
2262 | 663 urlpatterns = [ |
---|
2263 | 664 .... |
---|
2264 | 665 url(r'^listar-users/$', ListUsersAjaxView.as_view(), |
---|
2265 | 666 name="listar_users"), |
---|
2266 | 667 \end{verbatim} |
---|
2267 | 668 \end{frame} |
---|
2268 | 669 |
---|
2269 | 670 \begin{frame}[fragile] |
---|
2270 | 671 \begin{verbatim} |
---|
2271 | 672 Se anexa el siguiente código el archivo index.html |
---|
2272 | 673 En la parte visual: |
---|
2273 | 674 |
---|
2274 | 675 <div id="datatable"></div> |
---|
2275 | 676 |
---|
2276 | 677 Y en la parte de código javascript |
---|
2277 | 678 |
---|
2278 | 679 <script type="text/javascript"> |
---|
2279 | 680 $(document).ready(function() { |
---|
2280 | 681 $('#datatable').dataTable({ |
---|
2281 | 682 "processing": true, |
---|
2282 | 683 "serverSide": true, |
---|
2283 | 684 "ajax": {% url 'listar_user'%}, |
---|
2284 | 685 language: {url: JSON_DATA} |
---|
2285 | 686 }); |
---|
2286 | 687 $('#datatable') |
---|
2287 | 688 .removeClass('display') |
---|
2288 | 689 .addClass('table table-striped table-bordered'); |
---|
2289 | 690 }); |
---|
2290 | 691 </script> |
---|
2291 | 692 \end{verbatim} |
---|
2292 | 693 \end{frame} |
---|
2293 | 694 |
---|
2294 | 695 \subsection{Anexar registros} |
---|
2295 | 696 \begin{frame}[fragile] |
---|
2296 | 697 \begin{verbatim} |
---|
2297 | 698 Creamos el método en el archivo views.py |
---|
2298 | 699 |
---|
2299 | 700 def AnexarRegistro(request): |
---|
2300 | 701 if request.method == 'POST': |
---|
2301 | 702 |
---|
2302 | 703 vusername = request.POST['username'] |
---|
2303 | 704 u = User(username = vusername) |
---|
2304 | 705 u.save() |
---|
2305 | 706 message = _("El usuario fue creado") |
---|
2306 | 707 template = loader.get_template('personal/profile.html') |
---|
2307 | 708 context = {'message':message} |
---|
2308 | 709 return HttpResponse(template.render(context, request)) |
---|
2309 | 710 |
---|
2310 | 711 \end{verbatim} |
---|
2311 | 712 \end{frame} |
---|
2312 | 713 |
---|
2313 | 714 \subsection{Modificar y eliminar registros} |
---|
2314 | 715 \begin{frame}[fragile] |
---|
2315 | 716 \begin{verbatim} |
---|
2316 | 717 @login_required |
---|
2317 | 718 def change_profile(request): |
---|
2318 | 719 """ Cambiar perfil de usuario |
---|
2319 | 720 """ |
---|
2320 | 721 if request.method == 'POST': |
---|
2321 | 722 user_id = request.POST['user_id'] |
---|
2322 | 723 personal = User.objects.get(user_id=request.user.id) |
---|
2323 | 724 personal.first_name = request.POST['fname'] |
---|
2324 | 725 personal.last_name = request.POST['lname'] |
---|
2325 | 726 personal.email = request.POST['email'] |
---|
2326 | 727 personal.is_active = request.POST.get('is_active') |
---|
2327 | 728 personal.user.save() |
---|
2328 | 729 |
---|
2329 | 730 message = _("The profile change was made") |
---|
2330 | 731 context = {'personal':personal,'message':message,} |
---|
2331 | 732 template = loader.get_template('personal/profile.html') |
---|
2332 | 733 return HttpResponse(template.render(context, request)) |
---|
2333 | 734 |
---|
2334 | 735 \end{verbatim} |
---|
2335 | 736 \end{frame} |
---|
2336 | 737 |
---|
2337 | 738 \begin{frame}[fragile] |
---|
2338 | 739 \begin{verbatim} |
---|
2339 | 740 @login_required |
---|
2340 | 741 def delete_personal(request): |
---|
2341 | 742 """ Delete users |
---|
2342 | 743 """ |
---|
2343 | 744 id = json.loads(request.POST['seleccionados']) |
---|
2344 | 745 print id |
---|
2345 | 746 |
---|
2346 | 747 for id_values in id: |
---|
2347 | 748 if id_values["id"] != "0": |
---|
2348 | 749 |
---|
2349 | 750 u = User.objects.get(pk=int(id_values["id"])) |
---|
2350 | 751 u.delete() |
---|
2351 | 752 |
---|
2352 | 753 return redirect('personal') |
---|
2353 | 754 \end{verbatim} |
---|
2354 | 755 \end{frame} |
---|
2355 | 756 |
---|
2356 | 757 \subsection{View's} |
---|
2357 | 758 \begin{frame}[fragile] |
---|
2358 | 759 \begin{verbatim} |
---|
2359 | 760 #### ListView |
---|
2360 | 761 |
---|
2361 | 762 # En el archivo views.py |
---|
2362 | 763 |
---|
2363 | 764 from django.views.generic.list import ListView |
---|
2364 | 765 from django.utils import timezone |
---|
2365 | 766 |
---|
2366 | 767 from articles.models import Article |
---|
2367 | 768 |
---|
2368 | 769 class ArticleListView(ListView): |
---|
2369 | 770 |
---|
2370 | 771 model = Article |
---|
2371 | 772 |
---|
2372 | 773 def get_context_data(self, **kwargs): |
---|
2373 | 774 context = super(ArticleListView, |
---|
2374 | 775 self).get_context_data(**kwargs) |
---|
2375 | 776 context['now'] = timezone.now() |
---|
2376 | 777 return context |
---|
2377 | 778 |
---|
2378 | 779 \end{verbatim} |
---|
2379 | 780 \end{frame} |
---|
2380 | 781 |
---|
2381 | 782 \begin{frame}[fragile] |
---|
2382 | 783 \begin{verbatim} |
---|
2383 | 784 |
---|
2384 | 785 # En el archivo urls.py |
---|
2385 | 786 from django.conf.urls import url |
---|
2386 | 787 |
---|
2387 | 788 from article.views import ArticleListView |
---|
2388 | 789 |
---|
2389 | 790 urlpatterns = [ |
---|
2390 | 791 url(r'^$',ArticleListView.as_view(),name='article-list'), |
---|
2391 | 792 ] |
---|
2392 | 793 |
---|
2393 | 794 # El template |
---|
2394 | 795 <h1>Articles</h1> |
---|
2395 | 796 <ul> |
---|
2396 | 797 {% for article in object_list %} |
---|
2397 | 798 <li> |
---|
2398 | 799 {{ article.pub_date|date }} - {{ article.headline }} |
---|
2399 | 800 </li> |
---|
2400 | 801 {% empty %} |
---|
2401 | 802 <li>No articles yet.</li> |
---|
2402 | 803 {% endfor %} |
---|
2403 | 804 </ul> |
---|
2404 | 805 \end{verbatim} |
---|
2405 | 806 \end{frame} |
---|
2406 | 807 |
---|
2407 | 808 \begin{frame}[fragile] |
---|
2408 | 809 \begin{verbatim} |
---|
2409 | 810 #### DetailView |
---|
2410 | 811 |
---|
2411 | 812 # En el archivo views.py |
---|
2412 | 813 |
---|
2413 | 814 from django.views.generic.detail import DetailView |
---|
2414 | 815 from django.utils import timezone |
---|
2415 | 816 |
---|
2416 | 817 from articles.models import Article |
---|
2417 | 818 |
---|
2418 | 819 class ArticleDetailView(DetailView): |
---|
2419 | 820 |
---|
2420 | 821 model = Article |
---|
2421 | 822 |
---|
2422 | 823 def get_context_data(self, **kwargs): |
---|
2423 | 824 context = super(ArticleDetailView, self). |
---|
2424 | 825 get_context_data(**kwargs) |
---|
2425 | 826 context['now'] = timezone.now() |
---|
2426 | 827 return context |
---|
2427 | 828 |
---|
2428 | 829 \end{verbatim} |
---|
2429 | 830 \end{frame} |
---|
2430 | 831 |
---|
2431 | 832 \begin{frame}[fragile] |
---|
2432 | 833 \begin{verbatim} |
---|
2433 | 834 |
---|
2434 | 835 # En el archivo urls.py |
---|
2435 | 836 |
---|
2436 | 837 from django.conf.urls import url |
---|
2437 | 838 |
---|
2438 | 839 from article.views import ArticleDetailView |
---|
2439 | 840 |
---|
2440 | 841 urlpatterns = [ |
---|
2441 | 842 url(r'^(?P<slug>[-\w]+)/$',ArticleDetailView.as_view(), |
---|
2442 | 843 name='article-detail'), |
---|
2443 | 844 ] |
---|
2444 | 845 |
---|
2445 | 846 # El template |
---|
2446 | 847 |
---|
2447 | 848 <h1>{{ object.headline }}</h1> |
---|
2448 | 849 <p>{{ object.content }}</p> |
---|
2449 | 850 <p>Reporter: {{ object.reporter }}</p> |
---|
2450 | 851 <p>Published: {{ object.pub_date|date }}</p> |
---|
2451 | 852 <p>Date: {{ now|date }}</p> |
---|
2452 | 853 \end{verbatim} |
---|
2453 | 854 \end{frame} |
---|
2454 | 855 |
---|
2455 | 856 \begin{frame}[fragile] |
---|
2456 | 857 \begin{verbatim} |
---|
2457 | 858 #### CreateView |
---|
2458 | 859 |
---|
2459 | 860 from django.views.generic.edit import CreateView |
---|
2460 | 861 from myapp.models import Author |
---|
2461 | 862 |
---|
2462 | 863 class AuthorCreate(CreateView): |
---|
2463 | 864 model = Author |
---|
2464 | 865 fields = ['name'] |
---|
2465 | 866 |
---|
2466 | 867 # En el template |
---|
2467 | 868 |
---|
2468 | 869 <form action="" method="post">{% csrf_token %} |
---|
2469 | 870 {{ form.as_p }} |
---|
2470 | 871 <input type="submit" value="Save" /> |
---|
2471 | 872 </form> |
---|
2472 | 873 |
---|
2473 | 874 \end{verbatim} |
---|
2474 | 875 \end{frame} |
---|
2475 | 876 |
---|
2476 | 877 \begin{frame}[fragile] |
---|
2477 | 878 \begin{verbatim} |
---|
2478 | 879 #### UpdateView |
---|
2479 | 880 |
---|
2480 | 881 from django.views.generic.edit import UpdateView |
---|
2481 | 882 from myapp.models import Author |
---|
2482 | 883 |
---|
2483 | 884 class AuthorUpdate(UpdateView): |
---|
2484 | 885 model = Author |
---|
2485 | 886 fields = ['name'] |
---|
2486 | 887 template_name_suffix = '_update_form' |
---|
2487 | 888 |
---|
2488 | 889 # En el template |
---|
2489 | 890 |
---|
2490 | 891 <form action="" method="post">{% csrf_token %} |
---|
2491 | 892 {{ form.as_p }} |
---|
2492 | 893 <input type="submit" value="Update" /> |
---|
2493 | 894 </form> |
---|
2494 | 895 |
---|
2495 | 896 \end{verbatim} |
---|
2496 | 897 \end{frame} |
---|
2497 | 898 |
---|
2498 | 899 \begin{frame}[fragile] |
---|
2499 | 900 \begin{verbatim} |
---|
2500 | 901 #### DeleteView |
---|
2501 | 902 |
---|
2502 | 903 from django.views.generic.edit import DeleteView |
---|
2503 | 904 from django.urls import reverse_lazy |
---|
2504 | 905 from myapp.models import Author |
---|
2505 | 906 |
---|
2506 | 907 class AuthorDelete(DeleteView): |
---|
2507 | 908 model = Author |
---|
2508 | 909 success_url = reverse_lazy('author-list') |
---|
2509 | 910 |
---|
2510 | 911 # En el template |
---|
2511 | 912 |
---|
2512 | 913 <form action="" method="post">{% csrf_token %} |
---|
2513 | 914 <p>Are you sure you want to delete "{{ object }}"?</p> |
---|
2514 | 915 <input type="submit" value="Confirm" /> |
---|
2515 | 916 </form> |
---|
2516 | 917 |
---|
2517 | 918 \end{verbatim} |
---|
2518 | 919 \end{frame} |
---|
2519 | 920 |
---|
2520 | 921 \subsection{Crear Login} |
---|
2521 | 922 \begin{frame}[fragile] |
---|
2522 | 923 \begin{verbatim} |
---|
2523 | 924 Creamos la aplicacion user desde la consola: |
---|
2524 | 925 |
---|
2525 | 926 python manage.py startapp user |
---|
2526 | 927 |
---|
2527 | 928 Editamos el archivo user/views.py: |
---|
2528 | 929 |
---|
2529 | 930 # -*- coding: utf-8 -*- |
---|
2530 | 931 |
---|
2531 | 932 from django.shortcuts import render |
---|
2532 | 933 from django.contrib import messages |
---|
2533 | 934 from django.contrib.auth import ( |
---|
2534 | 935 authenticate, logout, login |
---|
2535 | 936 ) |
---|
2536 | 937 from django.contrib.auth.models import ( |
---|
2537 | 938 Group, Permission, User |
---|
2538 | 939 ) |
---|
2539 | 940 |
---|
2540 | 941 class LoginView(FormView): |
---|
2541 | 942 form_class = FormularioLogin |
---|
2542 | 943 template_name = 'users.login.html' |
---|
2543 | 944 success_url = '/inicio/' |
---|
2544 | 945 \end{verbatim} |
---|
2545 | 946 \end{frame} |
---|
2546 | 947 |
---|
2547 | 948 \begin{frame}[fragile] |
---|
2548 | 949 \begin{verbatim} |
---|
2549 | 950 def form_valid(self, form): |
---|
2550 | 951 |
---|
2551 | 952 usuario = form.cleaned_data['usuario'] |
---|
2552 | 953 contrasena = form.cleaned_data['contrasena'] |
---|
2553 | 954 usuario = authenticate(username=usuario,password=contrasena) |
---|
2554 | 955 |
---|
2555 | 956 if usuario is not None: |
---|
2556 | 957 login(self.request, usuario) |
---|
2557 | 958 messages.info(self.request,'Bienvenido %s has ingresado\ |
---|
2558 | 959 Sistema con el usuario %s \ |
---|
2559 | 960 ' % (usuario.first_name, |
---|
2560 | 961 usuario.username)) |
---|
2561 | 962 else: |
---|
2562 | 963 self.success_url = reverse_lazy('users:login') |
---|
2563 | 964 messages.warning(self.request,'Verifique su nombre y \ |
---|
2564 | 965 contraseña\ |
---|
2565 | 966 y vuelve a intertar') |
---|
2566 | 967 |
---|
2567 | 968 return super(LoginView, self).form_valid(form) |
---|
2568 | 969 |
---|
2569 | 970 \end{verbatim} |
---|
2570 | 971 \end{frame} |
---|
2571 | 972 |
---|
2572 | 973 \subsection{Registro de Usuarios} |
---|
2573 | 974 \begin{frame}[fragile] |
---|
2574 | 975 \begin{verbatim} |
---|
2575 | 976 #### Crear Permisos desde el shell ejecutar |
---|
2576 | 977 |
---|
2577 | 978 from myapp.models import BlogPost |
---|
2578 | 979 from django.contrib.auth.models import Permission |
---|
2579 | 980 from django.contrib.contenttypes.models import ContentType |
---|
2580 | 981 |
---|
2581 | 982 content_type = ContentType.objects.get_for_model(BlogPost) |
---|
2582 | 983 permission = Permission.objects.create( |
---|
2583 | 984 codename='can_publish', |
---|
2584 | 985 name='Can Publish Posts', |
---|
2585 | 986 content_type=content_type, |
---|
2586 | 987 ) |
---|
2587 | 988 |
---|
2588 | 989 \end{verbatim} |
---|
2589 | 990 \end{frame} |
---|
2590 | 991 |
---|
2591 | 992 \begin{frame}[fragile] |
---|
2592 | 993 \begin{verbatim} |
---|
2593 | 994 |
---|
2594 | 995 from django.contrib.auth.models import Permission, User |
---|
2595 | 996 from django.contrib.contenttypes.models import ContentType |
---|
2596 | 997 from django.shortcuts import get_object_or_404 |
---|
2597 | 998 |
---|
2598 | 999 from myapp.models import BlogPost |
---|
2599 | 1000 |
---|
2600 | 1001 def user_gains_perms(request, user_id): |
---|
2601 | 1002 user = get_object_or_404(User, pk=user_id) |
---|
2602 | 1003 # any permission check will |
---|
2603 | 1004 #cache the current set of permissions |
---|
2604 | 1005 user.has_perm('myapp.change_blogpost') |
---|
2605 | 1006 |
---|
2606 | 1007 content_type=ContentType.objects.get_for_model(BlogPost) |
---|
2607 | 1008 permission = Permission.objects.get( |
---|
2608 | 1009 codename='change_blogpost', |
---|
2609 | 1010 content_type=content_type, |
---|
2610 | 1011 ) |
---|
2611 | 1012 user.user_permissions.add(permission) |
---|
2612 | 1013 |
---|
2613 | 1014 \end{verbatim} |
---|
2614 | 1015 \end{frame} |
---|
2615 | 1016 |
---|
2616 | 1017 \subsection{Login required} |
---|
2617 | 1018 \begin{frame}[fragile] |
---|
2618 | 1019 \begin{verbatim} |
---|
2619 | 1020 |
---|
2620 | 1021 from django.contrib.auth.decorators import |
---|
2621 | 1022 login_required, permission_required |
---|
2622 | 1023 from django.views.generic import TemplateView |
---|
2623 | 1024 |
---|
2624 | 1025 from .views import VoteView |
---|
2625 | 1026 |
---|
2626 | 1027 urlpatterns = [ |
---|
2627 | 1028 url(r'^about/$', login_required( |
---|
2628 | 1029 TemplateView.as_view(template_name="secret.html"))), |
---|
2629 | 1030 url(r'^vote/$', permission_required( |
---|
2630 | 1031 'polls.can_vote')(VoteView.as_view())), |
---|
2631 | 1032 ] |
---|
2632 | 1033 |
---|
2633 | 1034 \end{verbatim} |
---|
2634 | 1035 \end{frame} |
---|
2635 | 1036 |
---|
2636 | 1037 \subsection{Recuperar contraseña por correo} |
---|
2637 | 1038 \begin{frame}[fragile] |
---|
2638 | 1039 \begin{verbatim} |
---|
2639 | 1040 def newpassword(request): |
---|
2640 | 1041 puser = request.POST['puser'] |
---|
2641 | 1042 try: |
---|
2642 | 1043 user = User.objects.get(username=puser) |
---|
2643 | 1044 randompass = ''.join([choice( |
---|
2644 | 1045 '1234567890qwertyuiopasdfghjklzxcvbnm') |
---|
2645 | 1046 for i in range(10)]) |
---|
2646 | 1047 print randompass |
---|
2647 | 1048 subject = _('System: New Password') |
---|
2648 | 1049 message = _('Your password is reset, new password: ') |
---|
2649 | 1050 + randompass |
---|
2650 | 1051 user.email_user("subject","message") |
---|
2651 | 1052 user.set_password(randompass) |
---|
2652 | 1053 user.save() |
---|
2653 | 1054 except: |
---|
2654 | 1055 print "error send mail" |
---|
2655 | 1056 mensaje = _("User not found") |
---|
2656 | 1057 return redirect('/authenticate/signin') |
---|
2657 | 1058 |
---|
2658 | 1059 \end{verbatim} |
---|
2659 | 1060 \end{frame} |
---|
2660 | 1061 |
---|
2661 | 1062 \subsection{Conceptos avanzados} |
---|
2662 | 1063 \begin{frame}[fragile] |
---|
2663 | 1064 \begin{verbatim} |
---|
2664 | 1065 Otros conceptos |
---|
2665 | 1066 |
---|
2666 | 1067 * Internacionalización |
---|
2667 | 1068 * Zonas Horarias |
---|
2668 | 1069 * Servidor Web |
---|
2669 | 1070 * Geodjango |
---|
2670 | 1071 * Django Rest |
---|
2671 | 1072 |
---|
2672 | 1073 Entre otros... |
---|
2673 | 1074 |
---|
2674 | 1075 \end{verbatim} |
---|
2675 | 1076 \end{frame} |
---|
2676 | 1077 |
---|
2677 | 1078 \begin{frame}[plain] |
---|
2678 | 1079 |
---|
2679 | 1080 |
---|
2680 | 1081 \begin{center} |
---|
2681 | 1082 |
---|
2682 | 1083 \font\endfont = cmss10 at 15.40mm |
---|
2683 | 1084 \color{Brown} |
---|
2684 | 1085 \endfont |
---|
2685 | 1086 \baselineskip 20.0mm |
---|
2686 | 1087 |
---|
2687 | 1088 CENDITEL |
---|
2688 | 1089 |
---|
2689 | 1090 \end{center} |
---|
2690 | 1091 |
---|
2691 | 1092 |
---|
2692 | 1093 \end{frame} |
---|
2693 | 1094 |
---|
2694 | 1095 |
---|
2695 | 1096 \end{document} |
---|
2696 | >>>>>>> 392f76c82d86075e983cee03fa4b240023981610 |
---|