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

SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
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
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsSnow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsHyundai Motor Group
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
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
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 

Recently uploaded (20)

E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
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
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsSnow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
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
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 

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