Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

É 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 ?

Slide 4

Slide 4 text

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 :)

Slide 5

Slide 5 text

Django 101 Requisição: GET /welcome

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

Django 101 Requisição: GET /welcome Resposta: HTML from django.shortcuts import render def welcome(request): return render(request, 'welcome.html')

Slide 12

Slide 12 text

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!

Slide 13

Slide 13 text

Django 102 - Listagem

Slide 14

Slide 14 text

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})

Slide 15

Slide 15 text

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')

Slide 16

Slide 16 text

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!

Slide 17

Slide 17 text

Aquele sentimento…

Slide 18

Slide 18 text

Aquele sentimento…

Slide 19

Slide 19 text

Class-based views geram uma maneira alternativa de implementar views como objetos Python ao invés de funções Class Based Views!

Slide 20

Slide 20 text

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?

Slide 21

Slide 21 text

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)

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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) ]

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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…

Slide 29

Slide 29 text

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…

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

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)

Slide 32

Slide 32 text

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)

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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})

Slide 37

Slide 37 text

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'

Slide 38

Slide 38 text

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!

Slide 39

Slide 39 text

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'

Slide 40

Slide 40 text

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})

Slide 41

Slide 41 text

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?

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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[-\w]+)', views.BookDetailByCodeView.as_view()), ] GET /mybooks/got

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

Você deve estar se perguntando… Como eu sabia quais métodos alterar?

Slide 46

Slide 46 text

ccbv.co.uk <3

Slide 47

Slide 47 text

ccbv.co.uk <3

Slide 48

Slide 48 text

ccbv.co.uk <3

Slide 49

Slide 49 text

ccbv.co.uk <3

Slide 50

Slide 50 text

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?

Slide 51

Slide 51 text

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)

Slide 52

Slide 52 text

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.

Slide 53

Slide 53 text

Usuário fez signup? Quero login automático!

Slide 54

Slide 54 text

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)

Slide 55

Slide 55 text

Sentindo falta de alguma coisa?

Slide 56

Slide 56 text

Sim! Autenticação!

Slide 57

Slide 57 text

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!

Slide 58

Slide 58 text

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())) ]

Slide 59

Slide 59 text

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!

Slide 60

Slide 60 text

Mas… e APIs?

Slide 61

Slide 61 text

Mas… e APIs?

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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