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

[DjangoCon Europe 2015] Demystifying Mixins with Django

[DjangoCon Europe 2015] Demystifying Mixins with Django

"Demystifying mixins with Django" is a 15 minutes talk I presented at DjangoCon 2015 in Cardiff, UK.

2a3082799c3df9a58d06bc1b81107752?s=128

Ana Balica

June 03, 2015
Tweet

Transcript

  1. Demystifying Mixins with Django

  2. @anabalica

  3. Mixins are a controlled way of adding functionality to classes.

  4. Mixins are not special language constructs.

  5. In fact, mixins are ordinary Python classes. 1 class SomeMixin(object):

    2 """My smart mixin""" 3 4 def test_method(self): 5 pass
  6. Why use mixins? to improve modularity

  7. When to use mixins? want to reuse a particular feature

    in a lot of different classes
  8. Properties • single responsibility • not meant to be extended

    • not meant to be instantiated
  9. None
  10. None
  11. In Python the concept of mixins is implemented using multiple

    inheritance.
  12. Order matters

  13. 1 class Foo(BaseFoo, SomeMixin): 2 pass base class mixin

  14. 1 class Foo(BaseFoo, SomeMixin): 2 pass

  15. 1 class Foo(SomeMixin, BaseFoo): 2 pass

  16. 1 # some_app/views.py 2 from django.views.generic import TemplateView 3 4

    5 class AboutView(TemplateView): 6 template_name = "about.html"
  17. 1 # some_app/views.py 2 from django.views.generic import TemplateView 3 4

    5 class AboutView(SomeMixin, TemplateView): 6 template_name = "about.html"
  18. My first mixin

  19. 1 # some_app/views.py 2 3 4 class LoginRequiredMixin(object): 5

  20. 1 # some_app/views.py 2 3 4 class LoginRequiredMixin(object): 5 6

    def dispatch(self, request, *args, **kwargs): 7
  21. 1 # some_app/views.py 2 from django.core.exceptions import PermissionDenied 3 4

    5 class LoginRequiredMixin(object): 6 7 def dispatch(self, request, *args, **kwargs): 8 if not request.user.is_authenticated(): 9 raise PermissionDenied 10
  22. 1 # some_app/views.py 2 from django.core.exceptions import PermissionDenied 3 4

    5 class LoginRequiredMixin(object): 6 7 def dispatch(self, request, *args, **kwargs): 8 if not request.user.is_authenticated(): 9 raise PermissionDenied 10 11 return super(LoginRequiredMixin, self).\ 12 dispatch(request, *args, **kwargs) 13
  23. 1 # some_app/views.py 2 from django.views.generic import TemplateView 3 4

    5 class AboutView(LoginRequiredMixin, TemplateView): 6 template_name = "about.html"
  24. LoginRequiredMixin TemplateView AboutView

  25. LoginRequiredMixin DetailView AboutView

  26. ListView LoginRequiredListView AboutView CreateView LoginRequiredCreateView AboutView DetailView LoginRequiredDetailView AboutView FormView

    LoginRequiredFormView AboutView MyView LoginRequiredMyView AboutView TemplateView LoginRequiredTemplateView AboutView
  27. LoginRequiredMixin TemplateView AboutView

  28. dispatch() get_context_data() get_template_names() check if user is logged in, has

    permission add new data to the context add more flexibility to the template names
  29. 1 # some_app/views.py 2 from django.views.generic import TemplateView 3 4

    5 class AboutView(TemplateView): 6 template_name = "about.html"
  30. dispatch() get_context_data() get_template_names() check if user is logged in, has

    permission add new data to the context add more flexibility to the template names
  31. docs.djangoproject.com/en/1.8/ref/ class-based-views/base/

  32. docs.djangoproject.com/en/1.8/ref/ class-based-views/base/

  33. docs.djangoproject.com/en/1.8/topics/ class-based-views/mixins/

  34. docs.djangoproject.com/en/1.8/topics/ class-based-views/mixins/

  35. ccbv.co.uk/

  36. django-braces Access Mixins Form Mixins Other Mixins

  37. With great power comes great responsibility

  38. Recap • single responsibility • plug-in functionality • isn’t creating

    a subtyping relation
  39. Go back to your views and start writing mixins to

    clean up the code.