SlideShare a Scribd company logo
1 of 26
Download to read offline
Class-based views

      Luka Zakrajšek
        @bancek

   Django Meet Ljubljana,
       22. maj 2012
Podatkovna baza

• baze ne potrebujemo, ker do vseh podatkov
  dostopamo preko REST-a
• radi bi uporabljali Session in Message
  framework
settings.py
...

AUTHENTICATION_BACKENDS = (
    'federweb.auth.models.RestEngineBackend',
)

INSTALLED_APPS = (
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.contenttypes',
    ...
)

SESSION_ENGINE = 'django.contrib.sessions.backends.file'
Avtentikacija


• uporabimo Django Auth framework
• potrebujemo lastni Authentication backend
Authentication backend
class RestEngineBackend(object):
    supports_object_permissions = False
    supports_anonymous_user = True

    def authenticate(self, username=None, password=None):
        users = federation.users.full()

        for user in users:
            if user.username == username and user.check_password(password):
                return user

        logger.error('Authentication failed for username %s' % username)

    def get_user(self, user_id):
        return federation.users.get(user_id) or None

backend = RestEngineBackend()

user_logged_in.disconnect(update_last_login)
App module mixin
class AppNodeMixin(object):
    def __init__(self, *args, **kwargs):
        super(AppNodeMixin, self).__init__(*args, **kwargs)

        self.app_name = getattr(self, 'app_name', None)
        self.node_name = getattr(self, 'node_name', None)
        self.action_name = getattr(self, 'action_name', None)

    def get_template_names(self):
        if self.template_name:
            return [self.template_name]

        action_name = self.action_name or self.node_name

        template = '%s/%s/%s.html' % (self.app_name, self.node_name, action_name)

        return [template]

    def get_context_data(self, **kwargs):
        ctx = super(AppNodeMixin, self).get_context_data(**kwargs)
        ctx['request'] = self.request
        return ctx
Role router
def profile_url(user):
    url_map = {
        'FederationCoordinator': reverse('federation'),
        'CloudAdministrator': reverse('provider'),
        'FederationUser': reverse('user')
    }

    roles = user.roles.all()

    for role in roles:
        if role.name in url_map:
            return url_map[role.name]

    logger.error('Unknown roles for user "%s"' % user)

def home(request):
    if request.user.is_authenticated():
        return HttpResponseRedirect(profile_url(request.user))
    else:
        return redirect_to_login(request.path)
Role required mixin
class RoleRequiredMixin(object):
    user_role = None

    @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):
        user = request.user

        if self.user_role:
            if not user or not user.is_authenticated():
                raise Http404

            roles = user.roles.all()

            for role in roles:
                if role.name == self.user_role:
                    return super(RoleRequiredMixin, self).dispatch(
                                                    request, *args, **kwargs)

        raise Http404
REST mixin


class RestMixin(object):
    model = None

    def get_context_data(self, **kwargs):
        ctx = super(RestMixin, self).get_context_data(**kwargs)
        ctx['model'] = self.model
        return ctx
REST detail mixin
class RestDetailMixin(object):
    model = None
    action_name = 'detail'

    def get_object(self, id):
        obj = self.model.get(id)
        if not obj:
            raise Http404('Object not found')
        return obj

    @cached_property
    def obj(self):
        return self.get_object(self.kwargs['id'])

    def get_context_data(self, **kwargs):
        ct = super(RestDetailMixin, self).get_context_data(**kwargs)
        ct['object'] = self.obj
        return ct
REST detail view



class RestDetailView(RestDetailMixin, TemplateView):
    pass
REST remove object view

class RestRemoveView(RedirectView):
    model = None
    message = None
    permanent = False

    def get(self, request, id, *args, **kwargs):
        obj = self.model.get(id)

        if not obj.delete():
            raise Http404

        if self.message:
            messages.success(self.request, self.message)

        return super(RestRemoveView, self).get(request, *args, **kwargs)
urls.py

urlpatterns = patterns('',
    url(r'^$', Dashboard.as_view(), name='federation'),

    url(r'^/providers$', ProvidersList.as_view(),
        name='federation_providers'),
    url(r'^/providers/create$', ProvidersCreate.as_view(),
        name='federation_providers_create'),
    url(r'^/providers/(?P<id>d+)/edit$', ProvidersEdit.as_view(),
        name='federation_providers_edit'),
    url(r'^/providers/(?P<id>d+)/remove$', ProvidersRemove.as_view(),
        name='federation_providers_remove'),

    ...
)
App views


class AppMixin(RoleRequiredMixin):
    app_name = 'federation'
    user_role = 'FederationCoordinator'

class Dashboard(AppMixin, AppNodeMixin, TemplateView):
    node_name = 'dashboard'

    # requires role: "FederationCoordinator"
    # renders template: "federation/dashboard/dashboard.html"
App base template
{% extends 'base.html' %}

{% load common ui %}

{% block head_title %}Federation{% endblock %}

{% block nav %}
  <li class="{%   block nav_dashboard %}{% endblock %}">
    <a href="{%   url federation %}">Dashboard</a>
  </li>
  <li class="{%   block nav_users %}{% endblock %}">
    <a href="{%   url federation_users %}">Users</a>
  </li>
  ...
{% endblock %}

{% block breadcrumbs %}
  {% url federation as url %}{% breadcrumb 'Home' url %}
{{ block.super }}
{% endblock %}
Module views
class ProvidersMixin(AppMixin, AppNodeMixin):
    node_name = 'providers'
    model = federation.providers
    # requires role "FederationCoordinator"

class ProvidersList(ProvidersMixin, RestMixin, TemplateView):
    pass
    # renders "federation/providers/providers.html"

class ProvidersEdit(ProvidersMixin, RestDetailMixin, FormView):
    action_name = 'edit'
    form_class = ProviderForm
    success_url = reverse_lazy('federation_providers')
    ...
    # renders "federation/providers/edit.html"

class ProvidersRemove(ProvidersMixin, RestRemoveView):
    message = u'Provider was successfully removed.'
    url = reverse_lazy('federation_providers')

    # redirects to "/federation/providers"
Module base template
{% extends 'federation/base.html' %}

{% load common ui %}

{% block head_title %}Providers{% endblock %}

{% block nav_providers %}active{% endblock %}

{% block subnav   %}
  <li class="{%   block subnav_providers %}{% endblock %}">
    <a href="{%   url federation_providers %}">Providers</a>
  </li>
  <li class="{%   block subnav_providers_create %}{% endblock %}">
    <a href="{%   url federation_providers_create %}">Create Provider</a>
  </li>
{% endblock %}

{% block breadcrumbs %}
  {% url federation_providers as url %}
  {% breadcrumb 'Providers' url %}{{ block.super }}
{% endblock %}
Module dashboard


{% extends 'federation/base.html' %}

{% load common ui %}

{% block nav_dashboard %}active{% endblock %}

{% block breadcrumbs %}{% endblock %}

{% block content %}
  <h2>Hey, {{ request.user.firstName}}</h2>
{% endblock %}
Objects list

{% extends 'federation/providers/base.html' %}

{% load common ui %}

{% block subnav_providers %}active{% endblock %}

{% block title %}
  <h2>Providers</h2>
{% endblock %}

{% block content %}
  {% for object in model.full %}
    <p>
      {{ object.name }}
      <a href="{% url federation_providers_edit object.id %}">Edit</a>
    </p>
  {% endfor %}
{% endblock %}
Object edit
{% extends 'federation/providers/base.html' %}
...
{% block breadcrumbs %}
  {% url federation_providers_edit object.id as url %}
  {% breadcrumb 'Edit provider' url %}{{ block.super }}
{% endblock %}

{% block title %}<h2>Edit Provider</h2>{% endblock title %}

{% block content %}
  <form action="" method="post" class="form-horizontal">
    <fieldset>
      {% csrf_token %}
      {% form_errors form %}
      {% form_field form.name 'Name' %}
      {% form_field form.provider_uri 'Provider URI' %}
      <button class="btn btn-primary" type="submit">Save</button>
    </fieldset>
  </form>
{% endblock %}
Izvorna koda projekta

• http://websvn.ow2.org/listing.php?
  repname=contrail&path=%2Ftrunk
  %2Ffederation%2Ffederation-web%2Fsrc
  %2Ffederweb%2F
Vprašanja?


• Hvala za pozornost!

More Related Content

What's hot

First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentNuvole
 
Optimizing Angular Performance in Enterprise Single Page Apps
Optimizing Angular Performance in Enterprise Single Page AppsOptimizing Angular Performance in Enterprise Single Page Apps
Optimizing Angular Performance in Enterprise Single Page AppsMorgan Stone
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form componentSamuel ROZE
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patternsSamuel ROZE
 
WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...
WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...
WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...allilevine
 
Introduction to backbone presentation
Introduction to backbone presentationIntroduction to backbone presentation
Introduction to backbone presentationBrian Hogg
 
Hi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab PresentationHi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab Presentationplindner
 
Functionality Focused Code Organization
Functionality Focused Code OrganizationFunctionality Focused Code Organization
Functionality Focused Code OrganizationRebecca Murphey
 
Beyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS AppsBeyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS AppsRebecca Murphey
 
Magento Dependency Injection
Magento Dependency InjectionMagento Dependency Injection
Magento Dependency InjectionAnton Kril
 
WordPress plugin #3
WordPress plugin #3WordPress plugin #3
WordPress plugin #3giwoolee
 
Special Events: Beyond Custom Events
Special Events: Beyond Custom EventsSpecial Events: Beyond Custom Events
Special Events: Beyond Custom EventsBrandon Aaron
 
Building iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoBuilding iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoRob Bontekoe
 

What's hot (18)

Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
The Rails Way
The Rails WayThe Rails Way
The Rails Way
 
The Settings API
The Settings APIThe Settings API
The Settings API
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven Development
 
Optimizing Angular Performance in Enterprise Single Page Apps
Optimizing Angular Performance in Enterprise Single Page AppsOptimizing Angular Performance in Enterprise Single Page Apps
Optimizing Angular Performance in Enterprise Single Page Apps
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form component
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patterns
 
WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...
WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...
WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...
 
Introduction to backbone presentation
Introduction to backbone presentationIntroduction to backbone presentation
Introduction to backbone presentation
 
Hi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab PresentationHi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab Presentation
 
Functionality Focused Code Organization
Functionality Focused Code OrganizationFunctionality Focused Code Organization
Functionality Focused Code Organization
 
Beyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS AppsBeyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS Apps
 
Get AngularJS Started!
Get AngularJS Started!Get AngularJS Started!
Get AngularJS Started!
 
Magento Dependency Injection
Magento Dependency InjectionMagento Dependency Injection
Magento Dependency Injection
 
WordPress plugin #3
WordPress plugin #3WordPress plugin #3
WordPress plugin #3
 
Special Events: Beyond Custom Events
Special Events: Beyond Custom EventsSpecial Events: Beyond Custom Events
Special Events: Beyond Custom Events
 
Building iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoBuilding iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" Domino
 

Similar to Django Class-based views (Slovenian)

Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Fabien Potencier
 
PHPConf-TW 2012 # Twig
PHPConf-TW 2012 # TwigPHPConf-TW 2012 # Twig
PHPConf-TW 2012 # TwigWake Liu
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneRafael Felix da Silva
 
Easy rest service using PHP reflection api
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection apiMatthieu Aubry
 
Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4DEVCON
 
Gae Meets Django
Gae Meets DjangoGae Meets Django
Gae Meets Djangofool2nd
 
Ch9 .Best Practices for Class-Based Views
Ch9 .Best Practices  for  Class-Based ViewsCh9 .Best Practices  for  Class-Based Views
Ch9 .Best Practices for Class-Based ViewsWilly Liu
 
Django workshop : let's make a blog
Django workshop : let's make a blogDjango workshop : let's make a blog
Django workshop : let's make a blogPierre Sudron
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejsNick Lee
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelpauldix
 

Similar to Django Class-based views (Slovenian) (20)

Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
 
PHPConf-TW 2012 # Twig
PHPConf-TW 2012 # TwigPHPConf-TW 2012 # Twig
PHPConf-TW 2012 # Twig
 
Django Vs Rails
Django Vs RailsDjango Vs Rails
Django Vs Rails
 
AngularJs-training
AngularJs-trainingAngularJs-training
AngularJs-training
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com Backbone
 
Django
DjangoDjango
Django
 
Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
 
Easy rest service using PHP reflection api
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection api
 
Backbone Basics with Examples
Backbone Basics with ExamplesBackbone Basics with Examples
Backbone Basics with Examples
 
Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4
 
Gae Meets Django
Gae Meets DjangoGae Meets Django
Gae Meets Django
 
Ch9 .Best Practices for Class-Based Views
Ch9 .Best Practices  for  Class-Based ViewsCh9 .Best Practices  for  Class-Based Views
Ch9 .Best Practices for Class-Based Views
 
Django workshop : let's make a blog
Django workshop : let's make a blogDjango workshop : let's make a blog
Django workshop : let's make a blog
 
Django Bogotá. CBV
Django Bogotá. CBVDjango Bogotá. CBV
Django Bogotá. CBV
 
Flask – Python
Flask – PythonFlask – Python
Flask – Python
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModel
 

More from Luka Zakrajšek

Emscripten, asm.js, and billions of math ops
Emscripten, asm.js, and billions of math opsEmscripten, asm.js, and billions of math ops
Emscripten, asm.js, and billions of math opsLuka Zakrajšek
 
How we migrated our huge AngularJS app from CoffeeScript to TypeScript
How we migrated our huge AngularJS app from CoffeeScript to TypeScriptHow we migrated our huge AngularJS app from CoffeeScript to TypeScript
How we migrated our huge AngularJS app from CoffeeScript to TypeScriptLuka Zakrajšek
 
SOA with Thrift and Finagle
SOA with Thrift and FinagleSOA with Thrift and Finagle
SOA with Thrift and FinagleLuka Zakrajšek
 
Typesafe stack - Scala, Akka and Play
Typesafe stack - Scala, Akka and PlayTypesafe stack - Scala, Akka and Play
Typesafe stack - Scala, Akka and PlayLuka Zakrajšek
 

More from Luka Zakrajšek (7)

Emscripten, asm.js, and billions of math ops
Emscripten, asm.js, and billions of math opsEmscripten, asm.js, and billions of math ops
Emscripten, asm.js, and billions of math ops
 
How we migrated our huge AngularJS app from CoffeeScript to TypeScript
How we migrated our huge AngularJS app from CoffeeScript to TypeScriptHow we migrated our huge AngularJS app from CoffeeScript to TypeScript
How we migrated our huge AngularJS app from CoffeeScript to TypeScript
 
Go for Rubyists
Go for RubyistsGo for Rubyists
Go for Rubyists
 
Let's Go-lang
Let's Go-langLet's Go-lang
Let's Go-lang
 
SOA with Thrift and Finagle
SOA with Thrift and FinagleSOA with Thrift and Finagle
SOA with Thrift and Finagle
 
AngularJS
AngularJSAngularJS
AngularJS
 
Typesafe stack - Scala, Akka and Play
Typesafe stack - Scala, Akka and PlayTypesafe stack - Scala, Akka and Play
Typesafe stack - Scala, Akka and Play
 

Recently uploaded

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 

Recently uploaded (20)

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 

Django Class-based views (Slovenian)

  • 1. Class-based views Luka Zakrajšek @bancek Django Meet Ljubljana, 22. maj 2012
  • 2. Podatkovna baza • baze ne potrebujemo, ker do vseh podatkov dostopamo preko REST-a • radi bi uporabljali Session in Message framework
  • 3. settings.py ... AUTHENTICATION_BACKENDS = ( 'federweb.auth.models.RestEngineBackend', ) INSTALLED_APPS = ( 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.contenttypes', ... ) SESSION_ENGINE = 'django.contrib.sessions.backends.file'
  • 4. Avtentikacija • uporabimo Django Auth framework • potrebujemo lastni Authentication backend
  • 5. Authentication backend class RestEngineBackend(object): supports_object_permissions = False supports_anonymous_user = True def authenticate(self, username=None, password=None): users = federation.users.full() for user in users: if user.username == username and user.check_password(password): return user logger.error('Authentication failed for username %s' % username) def get_user(self, user_id): return federation.users.get(user_id) or None backend = RestEngineBackend() user_logged_in.disconnect(update_last_login)
  • 6.
  • 7. App module mixin class AppNodeMixin(object): def __init__(self, *args, **kwargs): super(AppNodeMixin, self).__init__(*args, **kwargs) self.app_name = getattr(self, 'app_name', None) self.node_name = getattr(self, 'node_name', None) self.action_name = getattr(self, 'action_name', None) def get_template_names(self): if self.template_name: return [self.template_name] action_name = self.action_name or self.node_name template = '%s/%s/%s.html' % (self.app_name, self.node_name, action_name) return [template] def get_context_data(self, **kwargs): ctx = super(AppNodeMixin, self).get_context_data(**kwargs) ctx['request'] = self.request return ctx
  • 8. Role router def profile_url(user): url_map = { 'FederationCoordinator': reverse('federation'), 'CloudAdministrator': reverse('provider'), 'FederationUser': reverse('user') } roles = user.roles.all() for role in roles: if role.name in url_map: return url_map[role.name] logger.error('Unknown roles for user "%s"' % user) def home(request): if request.user.is_authenticated(): return HttpResponseRedirect(profile_url(request.user)) else: return redirect_to_login(request.path)
  • 9. Role required mixin class RoleRequiredMixin(object): user_role = None @method_decorator(login_required) def dispatch(self, request, *args, **kwargs): user = request.user if self.user_role: if not user or not user.is_authenticated(): raise Http404 roles = user.roles.all() for role in roles: if role.name == self.user_role: return super(RoleRequiredMixin, self).dispatch( request, *args, **kwargs) raise Http404
  • 10. REST mixin class RestMixin(object): model = None def get_context_data(self, **kwargs): ctx = super(RestMixin, self).get_context_data(**kwargs) ctx['model'] = self.model return ctx
  • 11. REST detail mixin class RestDetailMixin(object): model = None action_name = 'detail' def get_object(self, id): obj = self.model.get(id) if not obj: raise Http404('Object not found') return obj @cached_property def obj(self): return self.get_object(self.kwargs['id']) def get_context_data(self, **kwargs): ct = super(RestDetailMixin, self).get_context_data(**kwargs) ct['object'] = self.obj return ct
  • 12. REST detail view class RestDetailView(RestDetailMixin, TemplateView): pass
  • 13. REST remove object view class RestRemoveView(RedirectView): model = None message = None permanent = False def get(self, request, id, *args, **kwargs): obj = self.model.get(id) if not obj.delete(): raise Http404 if self.message: messages.success(self.request, self.message) return super(RestRemoveView, self).get(request, *args, **kwargs)
  • 14. urls.py urlpatterns = patterns('', url(r'^$', Dashboard.as_view(), name='federation'), url(r'^/providers$', ProvidersList.as_view(), name='federation_providers'), url(r'^/providers/create$', ProvidersCreate.as_view(), name='federation_providers_create'), url(r'^/providers/(?P<id>d+)/edit$', ProvidersEdit.as_view(), name='federation_providers_edit'), url(r'^/providers/(?P<id>d+)/remove$', ProvidersRemove.as_view(), name='federation_providers_remove'), ... )
  • 15. App views class AppMixin(RoleRequiredMixin): app_name = 'federation' user_role = 'FederationCoordinator' class Dashboard(AppMixin, AppNodeMixin, TemplateView): node_name = 'dashboard' # requires role: "FederationCoordinator" # renders template: "federation/dashboard/dashboard.html"
  • 16. App base template {% extends 'base.html' %} {% load common ui %} {% block head_title %}Federation{% endblock %} {% block nav %} <li class="{% block nav_dashboard %}{% endblock %}"> <a href="{% url federation %}">Dashboard</a> </li> <li class="{% block nav_users %}{% endblock %}"> <a href="{% url federation_users %}">Users</a> </li> ... {% endblock %} {% block breadcrumbs %} {% url federation as url %}{% breadcrumb 'Home' url %} {{ block.super }} {% endblock %}
  • 17. Module views class ProvidersMixin(AppMixin, AppNodeMixin): node_name = 'providers' model = federation.providers # requires role "FederationCoordinator" class ProvidersList(ProvidersMixin, RestMixin, TemplateView): pass # renders "federation/providers/providers.html" class ProvidersEdit(ProvidersMixin, RestDetailMixin, FormView): action_name = 'edit' form_class = ProviderForm success_url = reverse_lazy('federation_providers') ... # renders "federation/providers/edit.html" class ProvidersRemove(ProvidersMixin, RestRemoveView): message = u'Provider was successfully removed.' url = reverse_lazy('federation_providers') # redirects to "/federation/providers"
  • 18. Module base template {% extends 'federation/base.html' %} {% load common ui %} {% block head_title %}Providers{% endblock %} {% block nav_providers %}active{% endblock %} {% block subnav %} <li class="{% block subnav_providers %}{% endblock %}"> <a href="{% url federation_providers %}">Providers</a> </li> <li class="{% block subnav_providers_create %}{% endblock %}"> <a href="{% url federation_providers_create %}">Create Provider</a> </li> {% endblock %} {% block breadcrumbs %} {% url federation_providers as url %} {% breadcrumb 'Providers' url %}{{ block.super }} {% endblock %}
  • 19. Module dashboard {% extends 'federation/base.html' %} {% load common ui %} {% block nav_dashboard %}active{% endblock %} {% block breadcrumbs %}{% endblock %} {% block content %} <h2>Hey, {{ request.user.firstName}}</h2> {% endblock %}
  • 20.
  • 21. Objects list {% extends 'federation/providers/base.html' %} {% load common ui %} {% block subnav_providers %}active{% endblock %} {% block title %} <h2>Providers</h2> {% endblock %} {% block content %} {% for object in model.full %} <p> {{ object.name }} <a href="{% url federation_providers_edit object.id %}">Edit</a> </p> {% endfor %} {% endblock %}
  • 22.
  • 23. Object edit {% extends 'federation/providers/base.html' %} ... {% block breadcrumbs %} {% url federation_providers_edit object.id as url %} {% breadcrumb 'Edit provider' url %}{{ block.super }} {% endblock %} {% block title %}<h2>Edit Provider</h2>{% endblock title %} {% block content %} <form action="" method="post" class="form-horizontal"> <fieldset> {% csrf_token %} {% form_errors form %} {% form_field form.name 'Name' %} {% form_field form.provider_uri 'Provider URI' %} <button class="btn btn-primary" type="submit">Save</button> </fieldset> </form> {% endblock %}
  • 24.
  • 25. Izvorna koda projekta • http://websvn.ow2.org/listing.php? repname=contrail&path=%2Ftrunk %2Ffederation%2Ffederation-web%2Fsrc %2Ffederweb%2F