Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Django Bogotá. CBV

Django Bogotá. CBV

Django Meetup Bogotá. Class Based Views with examples.
Source code: https://github.com/ctrl-alt-delete/cbvexamples

If you are looking for Django developer, contact me at http://vero4ka.info

cansadadeserfeliz

June 06, 2013
Tweet

More Decks by cansadadeserfeliz

Other Decks in Programming

Transcript

  1. Class Based Views
    RosBusinessConsulting
    www.vero4ka.info
    @vero4ka_ru

    View Slide

  2. View Slide

  3. Class Based Views Inspector
    http://ccbv.co.uk

    View Slide

  4. CBV vs. FBV

    View Slide

  5. Classes
    View
    TemplateView
    RedirectView
    ListView CreateView
    UpdateView
    DetailView
    DeleteView

    View Slide

  6. from django.views.generic import View
    class MyViewClass(View):
    def get(self, request, *args, **kwargs):
    context = # calcular lo que usted desea pasar al template
    return self.render_to_response(context)
    def post(self, request, *args, **kwargs):
    context = # calcular lo que usted desea pasar al template
    return self.render_to_response(context)
    View class

    View Slide

  7. Models

    View Slide

  8. class Rubrica(models.Model):
    title = models.CharField(u'Título', max_length=255)
    def __unicode__(self):
    return unicode(self.title)
    class Noticia(models.Model):
    is_published = models.BooleanField(u'Status', default=False)
    pub_date = models.DateTimeField(u'Fecha de publicación',
    default=datetime.datetime.now)
    author = models.ForeignKey(User, verbose_name=u"Autor")
    rubric = models.ForeignKey(Rubrica, verbose_name=u"Rúbrica")
    title = models.CharField(u'Título', max_length=500, default=u'')
    body = models.TextField(u'Contenido')
    def __unicode__(self):
    return self.title
    class Meta(object):
    ordering = ['-pub_date']
    Models

    View Slide

  9. URLs

    View Slide

  10. from django.conf.urls.defaults import patterns, url
    from django.views.generic import TemplateView
    from noticias import views
    urlpatterns = patterns("",
    # Index static page
    url(r'^$|^index/$', TemplateView.as_view(template_name='noticias/index.html'), name="index"),
    # List view
    url(r'^noticias/$', views.Noticias.as_view(), name="noticias"),
    # Update view
    url(r'^noticia/(?P\d+)/$', views.UpdateNoticia.as_view(), name="update_noticia"),
    # Create view
    url(r'^noticia/create/$', views.CreateNoticia.as_view(), name="create_noticia"),
    # Detail view
    url(r'^noticia/(?P\d+)/$', views.Noticia.as_view(), name="noticia"),
    # Delete view
    url(r'^noticia/delete/(?P\d+)/$', views.DeleteNoticia.as_view(), name="delete_noticia"),
    )
    URLs

    View Slide

  11. Views

    View Slide

  12. View:
    from django.views.generic import ListView
    from noticias.models import Noticia as NoticiasModel
    class Noticias(ListView):
    model = NoticiasModel
    template_name = "noticias/list.html"
    context_object_name = "noticias"
    Template:
    {% include "noticias/base.html" %}
    {% block main_content %}
    {% for noticia in noticias %}
    {{ noticia.title }}
    {% endfor %}
    {% endblock main_content %}
    ListView

    View Slide

  13. View Slide

  14. class Noticias(ListView):
    model = NoticiasModel
    template_name = "noticias/list.html"
    context_object_name = "noticias"
    def get_context_data(self, **kwargs):
    context = super(Noticias, self).get_context_data(**kwargs)
    context.update(page_title='Lista de nuestras noticias')
    return context
    def get_queryset(self):
    return super(NoticiasDeCine, self).get_queryset().filter(rubric__slug="cine")
    ListView
    añadir data
    al contexto
    modificar
    queryset

    View Slide

  15. View Slide

  16. View:
    class Noticias(ListView):
    model = NoticiasModel
    context_object_name = "noticias"
    paginate_by = 5
    Template:
    {% for noticia in noticias %}
    {{ noticia.title }}
    {% endfor %}
    {% if paginator.num_pages > 1 %}
    {% if page_obj.has_previous %}
    Anterior
    {% endif %}
    Pagina {{ page_obj.number }} de {{ page_obj.paginator.num_pages }}
    {% if page_obj.has_next %}
    Siguiente
    {% endif %}
    {% endif %}
    ListView
    paginación

    View Slide

  17. View Slide

  18. View:
    from django.views.generic import DetailView
    class Noticia(DetailView):
    model = NoticiasModel
    template_name = "noticias/detail.html"
    context_object_name = "noticia"
    Template:
    {{ noticia.pub_date }}
    {{ noticia.title }}
    {{ noticia.rubric }}
    {{ noticia.author }}
    {{ noticia.body }}
    URLs:
    url(r'^noticia/(?P\d+)/$', views.Noticia.as_view(), name="noticia"),
    DetailView
    buscar un
    objeto por pk

    View Slide

  19. View Slide

  20. View:
    from django.views.generic import DetailView
    class Pubrica(DetailView):
    model = RubricaModel
    template_name = "noticias/rubrica.html"
    slug_field = "slug"
    Template:

    Title: {{ object.title }}


    Slug: {{ object.slug }}

    URLs:
    url(r'^rubrica/(?P\w+)/$', views.Pubrica.as_view(), name="rubrica"),
    DetailView
    buscar un objeto
    por slug

    View Slide

  21. View Slide

  22. Form Views

    View Slide

  23. Form:
    from django import forms
    class ContactenosForm(forms.Form):
    email = forms.EmailField(label="Email")
    name = forms.CharField(label="Nombre")
    message = forms.CharField(label="Mensaje", widget=forms.Textarea())
    View:
    class Contactenos(FormView):
    form_class = ContactenosForm
    template_name = "noticias/contactenos.html"
    success_url = reverse_lazy("gracias")
    URLs:
    url(r'^contactenos/$', views.Contactenos.as_view(), name="contactenos"),
    url(r'^gracias/$', TemplateView.as_view(template_name='noticias/gracias.html'),
    name="gracias"),
    FormView

    View Slide

  24. Template:
    {% include "noticias/base.html" %}
    {% block main_content %}

    {% csrf_token %}

    {{ form }}



    Save




    {% endblock main_content %}
    FormView

    View Slide

  25. View Slide

  26. from django.shortcuts import redirect
    class Contactenos(FormView):
    form_class = ContactenosForm
    template_name = "noticias/contactenos.html"
    success_url = reverse_lazy("gracias")
    def form_valid(self, form):
    send_mail('Email de {0}'.format(form.cleaned_data["name"]),
    form.cleaned_data["message"], form.cleaned_data["email"]
    ['[email protected]'example.com], fail_silently=False)
    return redirect(self.get_success_url())
    FormView
    enviar un correo cuando el
    formulario es correcto

    View Slide

  27. View Slide

  28. Otros metodos:
    def form_invalid(self, form):
    """
    Acciones a realizar si el formulario es incorrecto.
    """
    return self.render_to_response(self.get_context_data(form=form))
    def get_initial(self):
    """
    Definir un diccionario que será utilizado para proveer los datos iniciales del formulario
    """
    return self.initial.copy()
    FormView

    View Slide

  29. Form:
    from django.forms import ModelForm
    from noticias.models import Noticia
    class NoticiaForm(ModelForm):
    class Meta():
    model = Noticia
    exclude = ('pub_date',)
    View:
    from django.views.generic import CreateView
    class CreateNoticia(CreateView):
    model = NoticiasModel
    template_name = "noticias/form.html"
    form_class = NoticiaForm
    success_url = reverse_lazy("noticias")
    CreateView

    View Slide

  30. View Slide

  31. View:
    from django.views.generic import UpdateView
    class UpdateNoticia(UpdateView):
    model = NoticiasModel
    template_name = "noticias/form.html"
    form_class = NoticiaForm
    success_url = reverse_lazy("noticias")
    URLs:
    url(r'^noticia/update/(?P\d+)/$', views.UpdateNoticia.as_view(), name="update_noticia"),
    UpdateView

    View Slide

  32. View Slide

  33. View:
    from django.views.generic import DeleteView
    class DeleteNoticia(DeleteView):
    model = NoticiasModel
    success_url = reverse_lazy("noticias")
    template_name = "noticias/delete_confirm.html"
    Template:

    {% csrf_token %}

    >Cancel

    Yes, I'm sure




    DeleteView

    View Slide

  34. View Slide

  35. Do one thing, and do it well
    The UNIX philosophy

    View Slide

  36. Mixin

    View Slide

  37. import json
    from django.http import HttpResponse
    class JSONResponseMixin(object):
    response_class = HttpResponse
    def render_to_response(self, context, **response_kwargs):
    response_kwargs['content_type'] = 'application/json'
    return self.response_class(
    self.convert_context_to_json(context),
    **response_kwargs
    )
    def convert_context_to_json(self, context):
    return json.dumps(context)
    class NoticiasJSON(JSONResponseMixin, ListView):
    model = NoticiasModel
    Mixin

    View Slide

  38. View Slide

  39. Decoradores

    View Slide

  40. ● En URLs:
    from django.contrib.auth.decorators import login_required as _lr
    urlpatterns = patterns("",
    url(r'^noticias/$', _lr(views.Noticias.as_view()), name="noticias"),
    )
    ● En Views:
    from django.contrib.auth.decorators import login_required
    from django.views.utils.decorators import method_decorator
    class Niticias(ListView):
    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
    return super(Niticias, self).dispatch(*args, **kwargs)
    Decoradores

    View Slide

  41. Gracias por su atención!
    Ejemplos:
    https://bitbucket.org/vero4ka/cbvexamples

    View Slide