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

Django Views: Boas Práticas

Django Views: Boas Práticas

Django estabelece uma arquitetura suficientemente adequada, com cada parte do sistema (views, models, templates, forms) exercendo uma função específica. No entanto, é fácil se render à tentação de incluir nas views regras de negócio do sistema. Focando no princípio DRY (Don’t Repeat Yourself) views infladas podem acarretar em repetição de blocos de código por todo o projeto. Um cálculo, uma queryset mais elaborada ou um checkout em um sistema de pagamento podem multiplicar os focos de bug no seu projeto. Nesta palestra pretendo abordar boas práticas, não só de Django Views, como também de Orientação a Objeto.

More Decks by Renato dos Santos Oliveira

Other Decks in Technology

Transcript

  1. Quem Recifense Co-fundador da Labcodes Software Studio Membro da Django

    Software Foundation Organizador da Python Brasil 2014 Recife/Porto de Galinhas Viciado em Café
  2. Lab o quê?! ...Codes Software Studio Studio de Software de

    Recife para o Mundo! Não fábrica Studio Python/Django/AngularJS/English all the time!
  3. Callables class  FirstClass:              def

     a_method(self,  *args,  **kwargs):                return  "Hello  World!"   >>>  first_object  =  FirstClass()   >>>  first_object.a_method()   'Hello  World!'  
  4. Callables class  SecondClass:        def  __call__(self):    

               return  "Hello  World!"   >>>  second_object  =  SecondClass()   >>>  second_object()   'Hello  World!'  
  5. • Texto • HTML • Imagem • XML • Json

    • Arquivos • Código HTTP
  6. Urls from  django.conf.urls  import  url   from  .  import  views

      urlpatterns  =  [        url(r'^posts/$',  views.list_posts),   ]  
  7. Views from  django.shortcuts  import  render   from  posts.models  import  Post

      def  list_posts(request):        posts  =  Post.objects.all()        return  render(                request,  'posts/list.html',                  {'posts':  posts}        )  
  8. Views from  django.conf.urls  import  url   from  .  import  views

      urlpatterns  =  [        url(r'^posts/$',  views.list_posts),        url(r'^posts/new/$',  views.create_post),   ]  
  9. Function Based Views def  create_post(request):        if  request.method

     ==  'POST':                form  =  PostForm(request.POST)                if  form.is_valid():                        form.save()                        return  redirect('success')        else:                form  =  PostForm()        return  render(                request,  'posts/create.html',                  {'form':  form}        )
  10. Class Based Views Organiza o código de acordo com os

    métodos HTTP (get, post, etc.) Extensíveis Técnicas de OO (Mixins, Herança múltipla) podem ser usadas para garantir reusabilidade de código
  11. Views from  django.shortcuts  import  render   from  posts.models  import  Post

      def  list_posts(request):        posts  =  Post.objects.all()        return  render(                request,  ‘posts/list.html',                {'posts':  posts}        )  
  12. from  django.shortcuts  import  render   from  django.views.generic  import  View  

    from  .models  import  Post   class  ListPostsView(View):        def  get(self,  request):                posts  =  Post.objects.all()                return  render(                        request,  ‘posts/list.html',                        {"posts":  posts}                ) Django Class Based View
  13. URLs from  django.conf.urls  import  url   from  .  import  views

      urlpatterns  =  [        url(r'^posts/$',  views.list_posts),        url(r'^posts/new/$',  views.create_post),   ]  
  14. URLs from  django.conf.urls  import  url   from  .  import  views

      urlpatterns  =  [        url(r'^posts/$',  views.ListPostsView.as_view()),        url(r'^posts/new/$',  views.create_post),   ]  
  15. Function Based Views def  create_post(request):        if  request.method

     ==  'POST':                form  =  PostForm(request.POST)                if  form.is_valid():                        form.save()                        return  redirect('success')        else:                form  =  PostForm()        return  render(request,  'posts/create.html',  {'form' form})  
  16. Class Based Views class  PostFormView(View):        def  get(self,

     request,  *args,  **kwargs):                form  =  PostForm()                return  render(                        request,  ‘posts/create.html',                        {'form':  form})        def  post(self,  request,  *args,  **kwargs):                form  =  PostForm(request.POST)                if  form.is_valid():                        form.save()                        return  redirect('success')                return  render(                        request,  ‘posts/create.html',                        {'form':  form})  
  17. URLs from  django.conf.urls  import  url   from  .  import  views

      urlpatterns  =  [        url(r'^posts/$',  views.ListPostsView.as_view()),        url(r'^posts/new/$',  views.create_post),   ]  
  18. URLs from  django.conf.urls  import  url   from  .  import  views

      urlpatterns  =  [        url(r'^posts/$',  views.ListPostsView.as_view()),        url(r'^posts/new/$',                  views.PostFormView.as_view()),   ]  
  19. Generic Class Based Views • ListView • UpdateView • FormView

    • DeleteView • CreateView • DetailView • * Generic Dates • Redirect View • TemplateView • View
  20. class  PostFormView(View):        def  get(self,  request,  *args,  **kwargs):

                   form  =  PostForm()                return  render(request,  'posts/create.html',   {'form':  form})        def  post(self,  request,  *args,  **kwargs):                form  =  PostForm(request.POST)                if  form.is_valid():                        form.save()                        return  redirect('success')                return  render(request,  'posts/create.html',   {'form':  form})   Generic Class Based Views
  21. class  PostFormView(CreateView):        model  =  Post    

       fields  =  ['title',  'content']   Generic Class Based Views
  22. Template Default: {app_name}/{model_class_name}_{suffix}.html Form modelform_factory GET/POST Comportamento padrão já tratado

    pela create view E depois de criar o form? Tenta pegar a absolute url do objeto Tá, mas se eu não tenho essas coisas implementadas? Generic Class Based Views
  23. class  PostFormView(CreateView):        model  =  Post    

       form_class  =  PostForm        template_name  =  'posts/create.html'        success_url  =  reverse_lazy('success')   Generic Class Based Views
  24. Generic Class Based Views • get • post • get_queryset

    • get_success_url • get_object • get_template_names • as_view • dispatch • get_context_data
  25. Django Class Based View class  ListPostsView(ListView):        model

     =  Post   class  ListPostsView(ListView):        model  =  Post        queryset  =  Post.objects.filter(published=True)  
  26. Django Class Based View class  ListPostsView(ListView):        model

     =  Post   class  ListPostsView(ListView):        model  =  Post        queryset  =  Post.objects.filter(published=True)   class  ListPostsView(ListView):        model  =  Post        def  get_queryset(self):                return  Post.objects.filter(                        owner=self.request.user)  
  27. DRY

  28. “Every distinct concept and/or piece of code should live in

    one, and only one, place. Redundancy is bad. Normalization is good.”
  29. DRY Django Forms Validações Preparação de dados para renderização Criação

    de HTML Processamento de dados de form Managers/Querysets Busca/Inserção de dados Dar contexto às suas queries
  30. DRY Django Middlewares Processamento de request/response para todas as views

    Template filters Generalizar comportamento em templates
  31. Mixins class  MyMixin:        def  do_something(self):    

               return  "something  done!"   class  MyClass(MyBaseClass,  MyMixin):        pass
 >>>  my_object  =  MyClass()   >>>  my_object.do_something()   'something  done!'  
  32. Mixins class  FilterByOwnerMixin:        def  get_queryset(self):    

               if  self.queryset  is  not  None:                        return  self.queryset.filter(                                owner=self.request.user)                else:                        #  return  some  configuration  error   class  ListPostsView(ListView,  FilterByOwnerMixin):        model  =  Post  
  33. Mixins DRY Cuidado com o Mixin Hell Super considered Super

    - Raymond Hettinger (https://www.youtube.com/watch? v=EiOglTERPEo)
  34. Desacople! Onde vão suas regras de negócio? Django apps deveriam

    ser fácilmente plugáveis Acoplamento dificulta a reutilização das suas apps em outros projetos Camada de serviço