More Related Content Similar to Django Class-based views (Slovenian) Similar to Django Class-based views (Slovenian) (20) More from Luka Zakrajšek (7) Django Class-based views (Slovenian)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'
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)
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
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 %}
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 %}
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 %}
25. Izvorna koda projekta
• http://websvn.ow2.org/listing.php?
repname=contrail&path=%2Ftrunk
%2Ffederation%2Ffederation-web%2Fsrc
%2Ffederweb%2F