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

Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
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
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
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
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
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
 
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
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
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
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
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
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
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
 
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
 
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
 
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
 

Recently uploaded (20)

Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
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
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
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
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
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
 
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
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
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
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
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
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
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...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
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
 
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
 

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