jul 12, 2015
Hoy he estado programando en Django una vista para la descarga de informes, en
la que los usuarios registrados de una página pueden pedir un informe de la actividad
para un determinado año. La particularidad es que esos informes se generan de forma
dinámica en el momento de la petición, nada complicado pero antes de empezar a
programar he buscado que paquetes había disponibles, y me he encontrado
django-downloadview.
Con eso y un poco de código extra para comprobar que el usuario está autenticado
he solucionado el problema. Algunas veces CBV parecen magia.
#views.py
from django.shortcuts import render
from django.core.files.base import ContentFile
from django_downloadview import VirtualDownloadView
from django.http import HttpResponseForbidden, HttpResponseServerError
class LoginRequiredMixin(object):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated():
return HttpResponseForbidden()
else:
return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
class DownloadReportView(LoginRequiredMixin, VirtualDownloadView):
def generar_report(self, user, year):
# Generar contenido del informe para el usuario y fecha
return "Report content for {} {}".format(user.username, year)
def get_file(self):
# Metodo de VirtualDownloadView que devuelve el archivo virtual
report_name = 'report.txt'
return ContentFile(self.report_content, name=report_name)
def get(self, request, *args, **kwargs):
report_year = kwargs.get('year', None)
# El contenido del informe se genera aquí en lugar de en get_file, para
# simplificar la
try:
self.report_content=self.generate_report(request.user, report_year)
except Exception:
return HttpResponseServerError("There was an error while generating the report")
return super(DownloadReportView, self).get(request, *args, **kwargs)
Y el archivo urls.py para quien le pueda interesar:
#urls.py
from django.conf.urls import url
from .views import DownloadReportView
urlpatterns = [
url( # Handle report downloads
regex = r'^download_report/(?P<year>[0-9]{4})$',
view = DownloadReportView.as_view(),
name = 'download_user_report'),
]
Click to read and post comments
ene 01, 2015
Recientemente he tenido que crear un panel de control para una aplicación
django, su función era mostrar estadísticas de los pedidos. Como en
casi todos los casos el primer problema fue crear un sistema de login, esta
es una situación muy común que se presenta en la mayoría de aplicaciones,
la diferencia es que en este caso me decidí por usar Class Based Views,
y me he quedado sorprendido con la simplicidad y limpieza del código:
# views.py
from django.views.generic import FormView, TemplateView, RedirectView
# Authentication imports
from django.contrib.auth import login, logout
from django.contrib.auth.forms import AuthenticationForm
from django.core.urlresolvers import reverse_lazy
from cesta.models import Pedido
class LoginView(FormView):
form_class = AuthenticationForm
template_name = "control_panel/login.html"
success_url = reverse_lazy("panel-dashboard")
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated():
return HttpResponseRedirect(self.get_success_url())
else:
return super(LoginView, self).dispatch(request, *args, **kwargs)
def form_valid(self, form):
login(self.request, form.get_user())
return super(LoginView, self).form_valid(form)
class LogoutView(RedirectView):
pattern_name = 'panel-login'
def get(self, request, *args, **kwargs):
logout(request)
return super(LogoutView, self).get(request, *args, **kwargs)
class LoginRequiredMixin(object):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('panel-login'))
else:
return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
class ControlPanelView(LoginRequiredMixin, TemplateView):
template_name = 'control_panel/panel.html'
def get_context_data(self, **kwargs):
context = super(ControlPanelView, self).get_context_data(**kwargs)
context['pedidos_pendientes'] = Pedido.objects.pendientes()
# ....
# Recopilar resto de la informacion
# ....
return context
Descargar views.py
# urls.py
from django.conf.urls import patterns, url
from .views import ControlPanelView, LoginView, LogoutView
urlpatterns = patterns('',
url(
regex = r'^$',
view = ControlPanelView.as_view(),
name = "panel-dashboard"),
url(
regex = r'^login/$',
view = LoginView.as_view(),
name = "panel-login"),
url(
regex = r'^logout/$',
view = LogoutView.as_view(),
name = "panel-logout"),
)
Descargar urls.py
Por último un ejemplo para el template login.html:
{% extends 'base.html' %}
{% block content %}
<div class="login-panel">
<form method="post" role="form">{% csrf_token %}
{{ form.username }}
{{ form.password }}
<input type="submit" value="Login"/>
</form>
</div>
{% endblock %}
Click to read and post comments
ene 01, 2015
Recientemente he tenido que crear un panel de control para una aplicación
django, su función era mostrar estadísticas de los pedidos. Como en
casi todos los casos el primer problema fue crear un sistema de login, esta
es una situación muy común que se presenta en la mayoría de aplicaciones,
la diferencia es que en este caso me decidí por usar Class Based Views,
y me he quedado sorprendido con la simplicidad y limpieza del código:
# views.py
from django.views.generic import FormView, TemplateView, RedirectView
# Authentication imports
from django.contrib.auth import login, logout
from django.contrib.auth.forms import AuthenticationForm
from django.core.urlresolvers import reverse_lazy
from cesta.models import Pedido
class LoginView(FormView):
form_class = AuthenticationForm
template_name = "control_panel/login.html"
success_url = reverse_lazy("panel-dashboard")
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated():
return HttpResponseRedirect(self.get_success_url())
else:
return super(LoginView, self).dispatch(request, *args, **kwargs)
def form_valid(self, form):
login(self.request, form.get_user())
return super(LoginView, self).form_valid(form)
class LogoutView(RedirectView):
pattern_name = 'panel-login'
def get(self, request, *args, **kwargs):
logout(request)
return super(LogoutView, self).get(request, *args, **kwargs)
class LoginRequiredMixin(object):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('panel-login'))
else:
return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
class ControlPanelView(LoginRequiredMixin, TemplateView):
template_name = 'control_panel/panel.html'
def get_context_data(self, **kwargs):
context = super(ControlPanelView, self).get_context_data(**kwargs)
context['pedidos_pendientes'] = Pedido.objects.pendientes()
# ....
# Recopilar resto de la informacion
# ....
return context
Descargar views.py
# urls.py
from django.conf.urls import patterns, url
from .views import ControlPanelView, LoginView, LogoutView
urlpatterns = patterns('',
url(
regex = r'^$',
view = ControlPanelView.as_view(),
name = "panel-dashboard"),
url(
regex = r'^login/$',
view = LoginView.as_view(),
name = "panel-login"),
url(
regex = r'^logout/$',
view = LogoutView.as_view(),
name = "panel-logout"),
)
Descargar urls.py
Por último un ejemplo para el template login.html:
{% extends 'base.html' %}
{% block content %}
<div class="login-panel">
<form method="post" role="form">{% csrf_token %}
{{ form.username }}
{{ form.password }}
<input type="submit" value="Login"/>
</form>
</div>
{% endblock %}
Click to read and post comments