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

O que vem depois do Django Girls? Uma introdução às Class Based Views

O que vem depois do Django Girls? Uma introdução às Class Based Views

Palestra apresentada dia 23/06/2020 na Python XP organizado pela Vinta

96f6148ae5af63f90246a3817686b457?s=128

Leticia Portella

June 23, 2020
Tweet

More Decks by Leticia Portella

Other Decks in Technology

Transcript

  1. O que vem depois do tutorial do Django Girls Uma

    introdução às Class Based Views
  2. LETICIA PORTELLA /in/leportella @leportella @leleportella leportella.com pizzadedados.com

  3. É um tutorial que ensina pessoas a desenvolver usando o

    framework Django. Ao terminar o tutorial você tem uma aplicação web tot alment e funcional: um blog. https://tutorial.djangogirls.org/pt/ O que é o tutorial do ?
  4. Problema Esse é o Bob. O Bob tem uma livraria

    hipster e ele quer um sistema de catálogo de livros. O Bob está aprendendo a programar com o Django Girls :)
  5. Django 101 Requisição: GET /welcome

  6. Django 101 Requisição: GET /welcome urls.py

  7. Django 101 Requisição: GET /welcome urls.py views.py

  8. Django 101 Requisição: GET /welcome urls.py views.py def welcome():

  9. Django 101 Requisição: GET /welcome urls.py views.py def welcome(): models.py

  10. Django 101 Requisição: GET /welcome HTML urls.py views.py def welcome():

    models.py
  11. Django 101 Requisição: GET /welcome Resposta: HTML from django.shortcuts import

    render def welcome(request): return render(request, 'welcome.html')
  12. Django 102 - Listagem Requisição: GET /mybooks Resposta: HTML from

    django.shortcuts import render from .models import Book def get_books_list(request): books = Book.objects.all() return render(request, 'my-books.html', {'object_list': books}) Pega todos os livros!
  13. Django 102 - Listagem

  14. Django 103 - Detalhando um livro Requisição: GET /mybooks/1 Resposta:

    HTML Livro 1: A game of thrones from django.http import Http404 from django.shortcuts import render from .models import Book def get_book_by_id(request, pk): try: book = Book.objects.get(id=pk) except Book.DoesNotExist: raise Http404("Book does not exist") return render(request, 'my-book-detail.html', {'object': book})
  15. Django 104 - Atualização from django.http import Http404 from django.shortcuts

    import redirect, render from .forms import BookForm from .models import Book def edit_book(request, pk): try: book = Book.objects.get(id=pk) except Book.DoesNotExist: raise Http404("Book does not exist") if request.method == 'GET': form = BookForm(instance=book) return render(request, 'my-book-edit.html', {'form': form, 'object': book}) if request.method == 'POST': book = Book.objects.get(id=pk) form = BookForm(request.POST, instance=book) if form.is_valid(): form.save() return redirect('/old/my-books')
  16. Django 104 - Atualização from django.http import Http404 from django.shortcuts

    import redirect, render from .forms import BookForm from .models import Book def edit_book(request, pk): try: book = Book.objects.get(id=pk) except Book.DoesNotExist: raise Http404("Book does not exist") if request.method == 'GET': form = BookForm(instance=book) return render(request, 'my-book-edit.html', {'form': form, 'object': book}) if request.method == 'POST': book = Book.objects.get(id=pk) form = BookForm(request.POST, instance=book) if form.is_valid(): form.save() return redirect('/old/my-books') E nós nem cuidamos de todos os casos!
  17. Aquele sentimento…

  18. Aquele sentimento…

  19. Class-based views geram uma maneira alternativa de implementar views como

    objetos Python ao invés de funções Class Based Views!
  20. Organização de código código: você pode organizar os métodos HTTP

    em métodos separados As classes podem ser estendidas, permitindo reutilização de código Você pode usar vários Mixins pré-prontos para evitar reinventar a roda! Mas… porque usar o CBV?
  21. Class Based Views 101 from django.views import View from django.shortcuts

    import render class BookView(View): template_name = 'my-book.html' def get(self, request, *args, **kwargs): return render(request, self.template_name)
  22. from django.views import View from django.shortcuts import render from .forms

    import BookForm from .models import Book class BookView(View): form_class = BookForm template_name = 'my-book.html' def get(self, request, *args, **kwargs): return render(request, self.template_name) def post(self, request, *args, **kwargs): form = self.form_class(request.POST) if form.is_valid(): return render(request, 'success.html') return render(request, self.template_name, {'form': form}) Class Based Views 101
  23. Atenção ao urls.py! from django.urls import path from app import

    views urlpatterns = [ path('about/', views.welcome) ]
  24. Atenção ao urls.py! from django.urls import path from app.views import

    BookView urlpatterns = [ path('about/', BookView.as_view()) ] from django.urls import path from app import views urlpatterns = [ path('about/', views.welcome) ]
  25. E outros métodos HTTP? Requisição: GET /welcome

  26. Requisição: GET /welcome Resposta E outros métodos HTTP?

  27. Requisição: GET /welcome Resposta Requisição: HEAD /welcome Resposta parcial E

    outros métodos HTTP?
  28. from django.views import View from django.http import Response from .forms

    import BookForm from .models import Book class BookView(View): def head(self, *args, **kwargs): response = HttpResponse # … return response Outros métodos…
  29. from django.views import View from django.http import Response from .forms

    import BookForm from .models import Book class BookView(View): def head(self, *args, **kwargs): response = HttpResponse # … return response Outros métodos…
  30. None
  31. CBV 201 Requisição: GET /welcome Resposta: HTML from django.views import

    View from django.shortcuts import render class BookView(View): template_name = 'my-book.html' def get(self, request, *args, **kwargs): return render(request, self.template_name)
  32. CBV 201 Requisição: GET /welcome Resposta: HTML from django.views import

    View from django.shortcuts import render class BookView(View): template_name = 'my-book.html' def get(self, request, *args, **kwargs): return render(request, self.template_name)
  33. CBV 201 Requisição: GET /welcome Resposta: HTML from django.views.generic import

    TemplateView class WelcomeView(TemplateView): template_name = 'welcome.html'
  34. CBV 201 Requisição: GET /welcome Resposta: HTML from django.views.generic import

    TemplateView class WelcomeView(TemplateView): template_name = 'welcome.html'
  35. CBV 202 - Listagem from django.views.generic import ListView from .models

    import Book class BooksView(ListView): model = Book template_name = 'my-books.html'
  36. CBV 202 - Listagem from django.views.generic import ListView from .models

    import Book class BooksView(ListView): model = Book template_name = 'my-books.html' from django.shortcuts import render from .models import Book def get_books_list(request): books = Book.objects.all() return render(request, 'my-books.html', {'object_list': books})
  37. CBV 203 - Atualização from django.views.generic import UpdateView from .forms

    import BookForm from .models import Book class BookUpdateView(UpdateView): model = Book template_name = 'my-book-edit.html' form_class = BookForm success_url = '/my-books'
  38. CBV 203 - Atualização from django.views.generic import UpdateView from .forms

    import BookForm from .models import Book class BookUpdateView(UpdateView): model = Book template_name = 'my-book-edit.html' form_class = BookForm success_url = '/my-books' 13 linhas vs 4 linhas!
  39. CBV 204 - Detalhando um livro from django.views.generic import DetailView

    from .models import Book class BookDetailByIdView(DetailView): model = Book template_name = 'my-book-detail.html'
  40. CBV 204 - Detalhando um livro from django.views.generic import DetailView

    from .models import Book class BookDetailByIdView(DetailView): model = Book template_name = 'my-book-detail.html' from django.http import Http404 from django.shortcuts import render from .models import Book def get_book_by_id(request, pk): try: book = Book.objects.get(id=pk) except Book.DoesNotExist: raise Http404("Book does not exist") return render(request, 'my-book-detail.html', {'object': book})
  41. CBV 301 - E se a gente quiser um comportamento

    diferente? Todas as base class tem um comportamento específico. No caso do DetailView o padrão é buscar pelo ID. Mas e se eu quiser olhar para um atributo diferente?
  42. from django.views.generic import DetailView from .models import Book class BookDetailByCodeView(DetailView):

    model = Book template_name = 'my-book-detail.html' def get_object(self): return Book.objects.get(code=self.kwargs['code']) GET /mybooks/got
  43. from django.views.generic import DetailView from .models import Book class BookDetailByCodeView(DetailView):

    model = Book template_name = 'my-book-detail.html' def get_object(self): return Book.objects.get(code=self.kwargs['code']) # urls.py urlpatterns = [ url(r’^mybooks/(?P<code>[-\w]+)', views.BookDetailByCodeView.as_view()), ] GET /mybooks/got
  44. from django.views.generic import DetailView from .models import Book class BookDetailByCodeView(DetailView):

    model = Book template_name = 'my-book-detail.html' slug_field = 'code' slug_url_kwarg = 'code' GET /mybooks/got
  45. Você deve estar se perguntando… Como eu sabia quais métodos

    alterar?
  46. ccbv.co.uk <3

  47. ccbv.co.uk <3

  48. ccbv.co.uk <3

  49. ccbv.co.uk <3

  50. E se eu quisesse que a minha ListView não pegasse

    todos os livros, mas só os livros que ainda estão em estoque estoque?
  51. GET /mybooks from django.views.generic import ListView from .models import Book

    class BooksView(ListView): model = Book template_name = 'my-books.html' def get_queryset(self): return Book.filter(in_stock=True)
  52. GET /mybooks from django.views.generic import ListView from .models import Book

    class BooksView(ListView): model = Book template_name = 'my-books.html' def get_queryset(self): return Book.filter(in_stock=True) Um QuerySet (conjunto de busca) é, em essência, uma lista de objetos de um dado modelo.
  53. Usuário fez signup? Quero login automático!

  54. POST /signup from django.views.generic import CreateView from django.http import HttpResponseRedirect

    from django.contrib.auth import login from .forms import UserCreationForm class CreateUserView(ListView): form_class = UserCreationForm template_name = 'create-user.html' def form_valid(self): self.object = form.save() login(self.request, self.object) return HttpResponseRedirect('/', self.request.path)
  55. Sentindo falta de alguma coisa?

  56. Sim! Autenticação!

  57. from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic import DetailView from .models

    import Book class BookDetailView(LoginRequiredMixin, DetailView): model = Book template_name = 'my-book-detail.html' login_url = '/login' Autenticação está a apenas uma linha!
  58. Autenticação está a apenas uma linha! from django.contrib.auth.decorators import login_required

    from app.views import BookView urlpatterns = [ path('about/', login_required(BookView.as_view())) ]
  59. Bob está feliz :) Agora é possível fazer o sistema

    que ele quer, com poucas linhas de código mas com todas as funcionalidades que ele queria!
  60. Mas… e APIs?

  61. Mas… e APIs?

  62. from rest_framework import serializers, viewset from .models import Book #

    Serializers define the API representation class BookSerializer(serializer.HyperlinkModelSerializer): class Meta: model = Book fields = ['title'] class BookViewSet(viewset.ModelViewSet): queryset = Books.objects.all() serializer_class = BookSerializer Django Rest Framework
  63. Quer saber mais? https://github.com/leportella/class-based-views-example https://leportella.com/class-based-views-no-django.html or http://bit.ly/classbasedviews

  64. LETICIA PORTELLA /in/leportella @leportella @leleportella leportella.com pizzadedados.com