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...
settings.py...AUTHENTICATION_BACKENDS = (    federweb.auth.models.RestEngineBackend,)INSTALLED_APPS = (    django.contrib....
Avtentikacija• uporabimo Django Auth framework• potrebujemo lastni Authentication backend
Authentication backendclass RestEngineBackend(object):    supports_object_permissions = False    supports_anonymous_user =...
App module mixinclass AppNodeMixin(object):    def __init__(self, *args, **kwargs):        super(AppNodeMixin, self).__ini...
Role routerdef profile_url(user):    url_map = {        FederationCoordinator: reverse(federation),        CloudAdministra...
Role required mixinclass RoleRequiredMixin(object):    user_role = None    @method_decorator(login_required)    def dispat...
REST mixinclass RestMixin(object):    model = None    def get_context_data(self, **kwargs):        ctx = super(RestMixin, ...
REST detail mixinclass RestDetailMixin(object):    model = None    action_name = detail    def get_object(self, id):      ...
REST detail viewclass RestDetailView(RestDetailMixin, TemplateView):    pass
REST remove object viewclass RestRemoveView(RedirectView):    model = None    message = None    permanent = False    def g...
urls.pyurlpatterns = patterns(,    url(r^$, Dashboard.as_view(), name=federation),    url(r^/providers$, ProvidersList.as_...
App viewsclass AppMixin(RoleRequiredMixin):    app_name = federation    user_role = FederationCoordinatorclass Dashboard(A...
App base template{% extends base.html %}{% load common ui %}{% block head_title %}Federation{% endblock %}{% block nav %} ...
Module viewsclass ProvidersMixin(AppMixin, AppNodeMixin):    node_name = providers    model = federation.providers    # re...
Module base template{% extends federation/base.html %}{% load common ui %}{% block head_title %}Providers{% endblock %}{% ...
Module dashboard{% extends federation/base.html %}{% load common ui %}{% block nav_dashboard %}active{% endblock %}{% bloc...
Objects list{% extends federation/providers/base.html %}{% load common ui %}{% block subnav_providers %}active{% endblock ...
Object edit{% extends federation/providers/base.html %}...{% block breadcrumbs %}  {% url federation_providers_edit object...
Izvorna koda projekta• http://websvn.ow2.org/listing.php?  repname=contrail&path=%2Ftrunk  %2Ffederation%2Ffederation-web%...
Vprašanja?• Hvala za pozornost!
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
Upcoming SlideShare
Loading in...5
×

Django Class-based views (Slovenian)

927

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
927
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Django Class-based views (Slovenian)

  1. 1. Class-based views Luka Zakrajšek @bancek Django Meet Ljubljana, 22. maj 2012
  2. 2. Podatkovna baza• baze ne potrebujemo, ker do vseh podatkov dostopamo preko REST-a• radi bi uporabljali Session in Message framework
  3. 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. 4. Avtentikacija• uporabimo Django Auth framework• potrebujemo lastni Authentication backend
  5. 5. Authentication backendclass 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 Nonebackend = RestEngineBackend()user_logged_in.disconnect(update_last_login)
  6. 6. App module mixinclass 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
  7. 7. Role routerdef 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)
  8. 8. Role required mixinclass 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
  9. 9. REST mixinclass RestMixin(object): model = None def get_context_data(self, **kwargs): ctx = super(RestMixin, self).get_context_data(**kwargs) ctx[model] = self.model return ctx
  10. 10. REST detail mixinclass 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
  11. 11. REST detail viewclass RestDetailView(RestDetailMixin, TemplateView): pass
  12. 12. REST remove object viewclass 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)
  13. 13. urls.pyurlpatterns = 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), ...)
  14. 14. App viewsclass AppMixin(RoleRequiredMixin): app_name = federation user_role = FederationCoordinatorclass Dashboard(AppMixin, AppNodeMixin, TemplateView): node_name = dashboard # requires role: "FederationCoordinator" # renders template: "federation/dashboard/dashboard.html"
  15. 15. 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 %}
  16. 16. Module viewsclass 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 = uProvider was successfully removed. url = reverse_lazy(federation_providers) # redirects to "/federation/providers"
  17. 17. 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 %}
  18. 18. 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 %}
  19. 19. 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 %}
  20. 20. 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 %}
  21. 21. Izvorna koda projekta• http://websvn.ow2.org/listing.php? repname=contrail&path=%2Ftrunk %2Ffederation%2Ffederation-web%2Fsrc %2Ffederweb%2F
  22. 22. Vprašanja?• Hvala za pozornost!
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×