Django Class-based views (Slovenian)

  • 827 views
Uploaded on

 

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
827
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
5
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 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 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. 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. 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. 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. 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. 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. REST detail viewclass RestDetailView(RestDetailMixin, TemplateView): pass
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. Izvorna koda projekta• http://websvn.ow2.org/listing.php? repname=contrail&path=%2Ftrunk %2Ffederation%2Ffederation-web%2Fsrc %2Ffederweb%2F
  • 22. Vprašanja?• Hvala za pozornost!