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

Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
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
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...apidays
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 

Recently uploaded (20)

Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
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...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 

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